我想創建一個知道不根據輸入參數實例化的類。對於一個簡單的例子,如果我想創建一個對象,只能存在如果其輸入參數中的一個是> 1,則在創建對象時返回除對象之外的東西
foo = new_object(0.1)
應返回到None
foo
而不是對象。
它讓我覺得作爲一個優雅的方式來創建對象,因爲這意味着我需要在類外沒有代碼,以決定是否要創建它還是不
有沒有辦法做到這一點,還是同樣有用,就這練習不好,爲什麼?
我想創建一個知道不根據輸入參數實例化的類。對於一個簡單的例子,如果我想創建一個對象,只能存在如果其輸入參數中的一個是> 1,則在創建對象時返回除對象之外的東西
foo = new_object(0.1)
應返回到None
foo
而不是對象。
它讓我覺得作爲一個優雅的方式來創建對象,因爲這意味着我需要在類外沒有代碼,以決定是否要創建它還是不
有沒有辦法做到這一點,還是同樣有用,就這練習不好,爲什麼?
你需要重寫__new__
- 確保它採用相同的參數__init__
:
class Test(object):
def __init__(self, value):
self.value = value
def __new__(cls, value):
if value > 1:
return object.__new__(cls)
return None
def __repr__(self):
return "Test value %d" % self.value
t1 = Test(2)
print repr(t1)
t2 = Test(1)
print repr(t2)
Python支持從__new__
返回不同類型的對象,但這是相當罕見的做法。
在您的使用情況,如果你是
和foo = Test(value) # will None if value <= 1
,這是你必須做很多次的東西之間
if value < 1:
foo = None
else:
foo = Test(value)
選擇的話,我肯定會考慮讓該類做它。
在這種情況下,你不擁有控制權new_object
你可以使自己的工廠函數:
def maybe_foo(value):
if value > 1:
return new_object(value)
return None
很明顯,這將是一個不好的做法,因爲很簡單的原因,沒有人這樣做。調用構造函數應該構造對象實例,而不是有選擇地決定它是否需要。構建對象時,您不需要檢查失敗。所以它有一個相當高的「wtf配額」,這從來就不是一個好主意。
這就是說,我不確定是否有可能,因爲__init__()
已經在實例創建之後運行(並且不以return self
結尾)。這是Python,我敢肯定可以發生一些事情。我的觀點是,這樣做是一個壞主意。
「沒有人這樣做」這種做法很罕見,不一定是壞事。 '__init__'是初始化器,只有在__new__(構造函數)返回一個與它所屬類相同的類型時才被調用。 – 2012-03-15 14:37:50
您可以覆蓋__new__()
以有效地將對象實例化轉換爲類似工廠的操作,就像您想在此處執行的操作一樣。我有時希望使用抽象基類的__new__()
作爲具體子類的工廠,只要具體子類的列表可以被限制和已知。只要確保它是你的問題的最佳解決方案,因爲它可能是不...
提高'ValueError'將是Python的解決方案。 – 2012-03-15 14:33:04
引發異常是通常的路線,但不是唯一的路線。還有其他Pythonic解決方案。 – 2012-03-15 14:53:51
但是如果你想要返回關於初始化失敗的具體信息,你能做到這一點,例外 – 2012-03-15 18:06:21