2013-04-29 172 views
0

我想定義一個類,它的方法定義爲__repr__,它只會寫出所有不屬於方法的屬性的名稱和值。我怎樣才能做到這一點?我已經設法這樣寫,但我意識到這不檢查屬性類型。Python:如何檢查對象的屬性是否是方法?

class Example: 
    def __repr__(self): 
     return "\n".join(["%s: %s" % (x, getattr(self, x)) for x in dir(self) if not x.startswith('__')]) 

這裏缺少的是對屬性類型的檢查。

+0

您可以使用inspect.ismethod發現如果屬性是一個方法類型:) – defactodeity 2013-04-29 17:51:05

回答

3

可以使用inspect這樣的事情:

from inspect import ismethod,getmembers 

class Example: 
    def __repr__(self): 
     return "\n".join("%s: %s" % (k, v) for (k,v) in getmembers(self,lambda x: not ismethod(x))) 

    def method(self): 
     return 1 

a = Example() 
a.foo = 'bar' 
print a 

這也拿起雙下劃線屬性(__module____doc__)。如果你不想要這些,你可以很容易地過濾出來。

+0

它也會選擇'@ property'和class變量。 – kennytm 2013-04-29 17:49:30

+0

我會認爲它*應該*選擇這兩種情況。絕對屬性對象。畢竟,從API的角度來看,屬性和屬性之間沒有區別......但我想這真的取決於OP想要的東西:)。 – mgilson 2013-04-29 17:51:58

1
+2

這樣做的缺點是,你可以做一個調用對象的屬性:'é = Example();例如,e.foo = lambda x:x * x'。 – mgilson 2013-04-29 17:36:16

+0

更好是[這個答案](http://stackoverflow.com/a/1260997/1322401)to [斷言變量是實例方法?](http://stackoverflow.com/questions/1259963/python-assert-that -variable-是實例方法)。 – 2013-04-29 17:37:06

1

假設你的類沒有定義__slots__你也可以只重複實例的__dict__(或通過vars() function)。

class Superclass: 
    def __init__(self, w): 
     self.w = w 

class Example(Superclass): 
    def __init__(self, x, y, z): 
     super().__init__(1234) 
     self.x = x 
     self.y = y 
     self.z = z 

    @property 
    def x_prop(self): 
     return self.x 

    @classmethod 
    def do_something(cls, z): 
     return str(cls) + str(z) 

    def __call__(self): 
     return 4444 

    class_property = 42 


    def __repr__(self): 
     return "\n".join("%s: [%s]" % (k, v) for (k,v) in vars(self).items()) 

example = Example(2, lambda y: z, '4') 
example2 = Example(example, 6j, b'90') 

print(repr(example2)) 

這將打印

x: [x: [2] 
y: [<function <lambda> at 0x7f9368b21ef0>] 
z: [4] 
w: [1234]] 
y: [6j] 
z: [b'90'] 
w: [1234] 
相關問題