我實際上會阻止將你不需要的變量初始化爲__init__
到一個任意的默認值。
如果是這樣的話,我的確質疑您使用面向對象,但是我確定有一個有效且可以理解的情況,其中__init__
不會做所有事情,並且該類需要通過添加其他屬性來進一步修改自己其他方法。
在我看來,測試運行可能想要使用它的方法時是否設置了變量的正確方法是使用hasattr
。在這種情況下,這是使用該方法的有效方法,並且測試只是以合理的方式切換行爲。
另一種方法是嘗試使用它並處理異常,並提供一些關於您的類的用戶做錯的用戶友好信息。在這種情況下,該方法需要在運行之前設置屬性。
即嗨,您已經初始化了該類,但在運行z_run
方法之前,您需要通過調用z_init
方法確保z
屬性存在。
另一種可以說是更pythonic的方式是僅僅記錄如何在文檔字符串中使用該方法,然後在異常使用時發生異常。這對第一次執行某些內容來說已經足夠了,然後您可以專注於下一個任務。這與上面的情況相同,該方法需要設置屬性。
我不喜歡將變量初始化爲任意默認值的原因是這可能會造成混淆(因爲它是任意的)並且是線路噪聲。
如果該值不武斷和簡單,可以爲您應在__init__
方法,其可覆蓋使用默認值來改變默認值。它實際上也可以是一個有效的初始狀態,這也是而不是任意,您應該在__init__
方法中設置它。
所以,真正的答案是這取決於,你或許應該避免它,如果你要麼通過其他方法添加屬性或屬性初始化爲任意值這樣質疑你OO的使用。
儘管Simeon Visser說要讓你的對象保持一致的狀態,但他沒有基於你的抽象例子的一致性的基礎。雖然Pylint對這類事情發出警告,但是皮棉計劃發出的警告很簡單,因此高級審閱者可以注意到通常表示代碼異味。我說高級審稿人是因爲真正的審稿人應該閱讀並理解你的所有代碼,因此不需要Pylint。
,打破經驗法則的例子:
class Mutant(object):
"""A mutant!"""
def __init__(self):
"""A mutant is born with only 1 eye and 1 mouth"""
self.eyes = 1
self.mouth = 1
self.location = 'Montana'
def roll_to(self, location):
"""If they have limbs, running is less dangerous"""
if hasattr(self, 'limbs'):
print 'Your mutant broke its limbs off!!'
del self.limbs
self.location = location
def run_to(self, location):
"""If they don't have limbs, running is not effective"""
if not hasattr(self, 'limbs'):
print 'Your mutant tries to run but he has no limbs.'
else:
self.location = location
def grow_limbs(self, number_of_limbs):
"""Ah, evolution!"""
assert number_of_limbs > 0, 'Cannot grow 0 or less limbs...'
if hasattr(self, 'limbs'):
self.limbs += number_of_limbs
else:
self.limbs = number_of_limbs
同意。一致性是關鍵 - 您不希望外人使用您的API或類處於無效狀態。 –
你能簡單地定義什麼'一致的狀態'的含義。這是否意味着在實例化之後不應該添加新的成員變量? – user1893354
@ user1893354你可以在實例化之後添加變量,但不應該可以創建一個對象,調用一個或多個方法並最終得到一個雜亂的對象。方法的行爲及其返回值應始終保持一致。例如,我們不能有一個報告「破損」和「功能正常」的Car類。 –