2016-10-14 28 views
1

我想查看一個屬性的實例是否已經存在於我的對象中。正如你在下面看到的,如果我的Dog對象有一個特定的屬性,我想通過do_something_if_has_aged方法做些事情。我如何檢查某個屬性是否已被聲明?通常你會檢查它是否存在有這樣的事情,它會返回False檢查方法已經在實例中嗎?

obj = None 
if obj: 
    print(True) 
else: 
    print(False) 

這裏是我最小的可重複的例子:

>>> class Dog: 
    def __init__(self, name, age): 
     self.name = name 
     self.age = age 
    def add_years(self, years): 
     self.age += years 
     self.has_aged = True 
    def do_something_if_has_aged(self): 
     if self.has_aged: 
      print("The dog has aged and is %d years closer to death" % self.years) 
     else: 
      print("The dog hasn't aged, apparently.") 


>>> dog = Dog('Spot', 3) 
>>> dog.age 
3 
>>> dog.do_something_if_has_aged() 
Traceback (most recent call last): 
    File "<pyshell#193>", line 1, in <module> 
    dog.do_something_if_has_aged() 
    File "<pyshell#190>", line 9, in do_something_if_has_aged 
    if not self.has_aged: 
AttributeError: 'Dog' object has no attribute 'has_aged' 
>>> dog.add_years(1) 
>>> dog.age 
4 
>>> dog.do_something_if_has_aged() 
The dog hasn't aged, apparently. 

顯然已經歲的狗,雖然。

我很抱歉,如果標題沒有反映我想傳達的內容;我是OOP的新手。

+1

你的情況是錯誤的:你應該做'如果self.has_aged'。 –

回答

3

而不是測試f或該屬性,在該類上設置一個默認值;如果一個實例屬性丟失Python將一個類的屬性,而不是:

class Dog: 
    has_aged = False # default for all instances 
    def __init__(self, name, age): 
     self.name = name 
     self.age = age 
    def add_years(self, years): 
     self.age += years 
     self.has_aged = True # sets an instance attribute 
    def do_something_if_has_aged(self): 
     if self.has_aged: 
      print("The dog has aged and is %d years closer to death" % self.years) 
     else: 
      print("The dog hasn't aged, apparently.") 

(請注意,我不得不反轉測試,如果self.has_aged真正你想進入的第一個分支,而不是其他的方式周圍)。

或者你可以在__init__屬性設置默認值:

class Dog: 
    def __init__(self, name, age): 
     self.name = name 
     self.age = age 
     self.has_aged = False 
    def add_years(self, years): 
     self.age += years 
     self.has_aged = True 
    def do_something_if_has_aged(self): 
     if self.has_aged: 
      print("The dog has aged and is %d years closer to death" % self.years) 
     else: 
      print("The dog hasn't aged, apparently.") 

您還可以測試,如果一個屬性存在與hasattr() function

def do_something_if_has_aged(self): 
    if hasattr(self 'has_aged') and self.has_aged: 
     print("The dog has aged and is %d years closer to death" % self.years) 
    else: 
     print("The dog hasn't aged, apparently.") 

,或者使用getattr() function用默認值:

def do_something_if_has_aged(self): 
    if not getattr(self 'has_aged', False): 
     print("The dog has aged and is %d years closer to death" % self.years) 
    else: 
     print("The dog hasn't aged, apparently.") 

然而,動態測試屬性不應該是您選擇的第一個選項;有一個類默認是更清潔。

+0

'has_aged'作爲類變量而不是實例變量(在'__init__'中定義)的優點是什麼? –

+1

@JosieThompson:這個變量只有一個副本(所以這是一個內存優勢);爲什麼當默認可以存儲在類中時爲所有實例提供該屬性? –

4

看起來你正在尋找hasattr內置功能:

>>> class Dog(object): 
...  pass 
... 
>>> a = Dog() 
>>> hasattr(a, 'age') 
False 
>>> a.age = 7 
>>> hasattr(a, 'age') 
True 

在你的情況,你可以修改如下:

def do_something_if_has_aged(self): 
    if hasattr(self, 'has_aged'): 
     pass # do your logic 
1

我會重寫__init__方法包括: self.has_aged = False避免必須做檢查:

class Dog(object): 
    def __init__(self, name, age): 
     self.name = name 
     self.age = age 
     self.has_aged = False # Starting value so it is guaranteed to be defined (unless explicitly deleted). 

現在,你班的其他同學應該像寫作一樣工作。但是,如果你想看看屬性已在對象上定義的,你可以這樣寫:

class Foo(object): 
    def set_bar(self): 
     self.bar = True # Define the attribute bar if it is not yet defined. 

    def is_bar_set(self): 
     return hasattr(self, 'bar') 
1

要檢查是否使用hasattr是完全正常的,但如果你正在尋找一種快速解決您代碼,你可以做手前初始化變量爲假:

class Dog: 
    has_aged = False 

,也是解決您的病情,因爲我認爲它應該是相反的:

def do_something_if_has_aged(self): 
    if self.has_aged: # instead of not self.has_aged 
    print("The dog has aged and is %d years closer to death" % self.years) 
    else: 
    print("The dog hasn't aged, apparently.") 
相關問題