2013-05-19 22 views
0

我想這樣的事情在Python:實現/調用返回不可變值的類的最佳方法?

result = SomeClass(some_argument) 

這裏是抓不過。我不希望結果是一個實例,而是一個不可變的對象(例如int)。基本上,類的孔角色正在返回從參數計算出的值。我正在使用類而不是DRY用途的函數。 由於上面的代碼不會工作,因爲它總是會返回SomeClass的實例,那麼最好的選擇是什麼?

我唯一的想法是有一個靜態方法,但我不喜歡它:

result = SomeClass.static_method(some_argument) 
+2

以何種方式使用類代替一個函數用於DRY目的? – BrenBarn

+0

'def SomeClass(arg):return arg * 42'? – mg007

+0

我有很多Django函數視圖有一些重複的代碼或代碼結構塊。所以我創建了一個抽象類來照顧鍋爐板,並繼承了這一點。 –

回答

3

您可以覆蓋__new__這是很少見一個好主意,和/或必要雖然...

>>> class Foo(object): 
...  def __new__(cls): 
...   return 1 
... 
>>> Foo() 
1 
>>> type(Foo()) 
<type 'int'> 

如果你不回的cls一個實例,__init__將永遠不會被調用。

+0

這就是我一直在尋找:)。但是,爲什麼它不是一個好主意? –

+0

這只是非常意想不到的行爲。 – mgilson

+0

我明白了。你是對的。對於該課程的用戶來說,這可能會讓人困惑。但是,當你有折扣= calculate_discount(價格)這樣的東西時,它是完美的。用戶不應該在意它實際上是一個班級。 –

0

如果你有一個工廠方法,基本上類的方法是要走的路。 關於結果 - 這真的取決於你追求什麼樣的不變性,但基本上namedtuple做了偉大的工作,用於封裝的東西,也是不可變的(像普通的元組):

from collections import namedtuple 
class FactoryClass(object): 
    _result_type = namedtuple('ProductClass', ['prod', 'sum']) 
    @classmethod 
    def make_object(cls, arg1, arg2): 
     return cls._result_type(prod=arg1 * arg2, sum=arg1 + arg2) 

>>> FactoryClass.make_object(2,3) 
ProductClass(prod=6, sum=5) 
>>> x = _ 
>>> x.prod = 3 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: can't set attribute 
相關問題