2013-04-29 120 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] 
相关问题