2017-08-19 28 views
0

__init__中,是否有一種很酷的使用類字段(類變量)作爲關鍵字參數的默認值的pythonic方法?
以下是示例:Python - 在__init__中使用類字段作爲關鍵字參數的值

class Foo(): 

    field = 5 

    def __init__(self, arg=field): # arg=Foo.field => name 'Foo' is not defined 
     self.arg = arg 

# ok, let's start 
obj_1 = Foo() 
print(obj_1.arg) # 5, cool 

# then I want to change Foo.field 
Foo.field = 10 
print(Foo.field) # 10, obviously 
obj_2 = Foo() 
print(obj_2.arg) # still 5, that's sad :(

爲什麼會發生這種情況?

我知道我可以做水木清華這樣的:

class Qux(): 

    field = 5 

    def __init__(self, arg='default'): 
     self.arg = {True:Qux.field, False:arg}[arg == 'default'] 


Qux.field= 10 
obj_3 = Qux() 
print(obj_3.arg) # 10 

但有一個更簡單的方法?
在此先感謝。

+0

等待,這不是無論這些問題的副本... –

+0

這不是,但這些問題的信息是有幫助的。其實,[Fred Foo的回答](https://stackoverflow.com/a/5555470/8488611)解釋了一切 - 「默認參數是在函數定義時評估的,而不是在通話時評估的」。所以,關鍵字參數的默認值,包括在一個類內,總是指向同一個對象,在我的情況下 - 不可變5.如果我想改變一個默認值,我應該使用一個可變類型,比如'field = [5 ]' 'self.arg = arg [0]',然後'Foo.field [0] = 10'。它會正常工作,但它比我的Qux的例子更難看:) – KalyanKruno

+0

您也可以使用類屬性或自定義的可變整數對象。 –

回答

0

只需將參數設置爲None即可。然後測試參數None是否在__init__。如果是這樣,將其設置爲它的默認值:

class Foo(): 
    field = 5 
    def __init__(self, arg=None): 
     if arg is None: 
      self.arg = Foo.field 
     else: 
      self.arg = arg 

上述邏輯也可以被濃縮爲:

self.arg = Foo.field if arg is None else arg 
+0

我在Qux的例子中也做了同樣的事情。有一種更簡單的方法嗎? – KalyanKruno

相關問題