2017-10-08 87 views
0

我希望我的班,以检查是否:解决:检查类属性:方法,属性或不存在

  1. 所需的属性存在
  2. 如果它是一个方法,它应该返回方法的结果
  3. 如果它是一个属性,返回值
  4. 如果不存在,引发一个AttributeException

我的解决方案(不工作):

class A: 
    def __getattr__(self, item): 
     try: 
      return self.item() 
     except AttributeError: 
      try: 
       return self.item 
      except AttributeError: 
       raise AttributeError 

    y = 2 
    def x(self): 
    return 1 

我的测试:

a = A() 
print(a.x) 

我的结果:

<bound method A.x of <__main__.A object at 0x7f992de18c50>> 

正如你所看到的,它返回到函数的引用,而不是它的结果。我哪里做错了?

[UPD]:嗯,也许我的英语很糟糕,所以我不能告诉我的想法是正确的。 无论如何,我的问题是通过使用解决

@property 

装饰。 我只想要 - 将方法称为属性

+0

'__getattr__'是只对传统方式找不到的标识符进行调用 - 访问“ax”不会调用该方法。这同样适用,因为你的实现也被破坏了 - self.item将是属性* named *'item',而不是具有字符串参数'item'的名称的属性。 – jonrsharpe

回答

0

__getattr__仅在常规查找找不到该项目时才会调用。当你查找一个项目时,首先运行对象的__getattribute__。如果它提高AttributeError(它没有在对象的字典中找到它) - 那么它调用__getattr__

您的代码返回的原因bound method从未执行过__getattribute__代码,因为该属性是通过常规查找过程找到的。即使它被执行,也不会起作用。 item是一个保存参数的变量。 self.item不存在;要做到这一点的方法是使用attr = getattr(self, item)

你需要的是@property,让您的接入方式,如他们的属性:

... class code ... 

    @property 
    def x(self): 
     return 1 

a = A() 
print a.x 
1 

注意,你不能再调用属性的功能:

a.x() 
Traceback (most recent call last): 
    File "C:\Python27\tests\test.py", line 12, in <module> 
    print a.x() 
TypeError: 'int' object is not callable 
0

这是Python的工作方式。方法只是类型绑定方法的属性。

你可以使这项工作更好,但只是启发式。例如。如果你想禁止绑定方法,请检查类型,然后调用。

但是,这意味着如果返回该绑定方法,那么它会陷入麻烦,因为它应该是属性提供的回调。

您也可以检查对象的 -Attribute如果有一个财产申报对于给定的名称等

总之,我会质疑你的方法。有一个简单的解决方案:不要假设什么是事情,让用户做出这个决定。

+0

我不知道为什么它返回一个绑定的方法,而不是它的执行结果? –

+0

正如我所说 - 你可以通过检查类型“绑定方法”来解决这个问题。但是这将是一种启发式的方法:如果该属性应该返回一个绑定方法,那么您将进入下一次不按预期工作的迭代。这可能会或可能不会成为您具体使用案例的问题,但不存在一个通用的解决方案。 – deets