2017-10-08 84 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