2012-08-03 187 views
1

這裏是我的課吧:如何使用非默認參數的值作爲Python中默認參數的默認值?

class Bar: 
    def __init__(self, start, end, open, volume, high=open, low=open, last=open): 
     self.start = start 
     self.end = end 
     self.open = open 
     self.high = high 
     self.low = low 
     self.last = last 
     self.volume = int(volume) 

    def __str__(self): 
     return self.start.strftime("%m/%d/%Y\t%H:%M:%S") + "\t" + self.end.strftime("%H:%M:%S") + "\t" +str(self.open) + "\t" + str(self.high) + "\t" + str(self.low) + "\t" + str(self.last) + "\t" + str(self.volume) 

1)我想初始化高,低,最後因爲種種開放的。這是正確的方法嗎?

2)當我這樣做印刷(STR(巴))我得到有趣的輸出,如...

03/13/2012 12:30:00 13:30:00 138.91 <built-in function open> 138.7 <built-in function open> 13177656

回答

5

如果你寫你的函數作爲

def __init__(self, start, end, foo, volume, high=foo, low=foo, last=foo): 
    self.start = start 
    self.end = end 
    self.open = foo 
    self.high = high 
    self.low = low 
    self.last = last 
    self.volume = int(volume) 

你會得到一個NameError抱怨名稱foo沒有定義。這是因爲參數的默認值無法引用另一個參數,當您嘗試採用其值時,尚未定義其他參數。 (定義該方法時的默認值被設定,而不是當它被調用。)

然而,open是在Python內置函數,所以它被定義;它只是不是你想要的open。要做到這一點,正確的方法是可能

class Bar: 
    def __init__(self, start, end, open, volume, high=None, low=None, last=None): 
     self.start = start 
     self.end = end 
     self.open = open 
     self.high = open if high is None else high 
     self.low = open if low is None else low 
     self.last = open if last is None else last 
     self.volume = int(volume) 

此外,你可能想使用的,而不是「開放」作爲參數名「open_」,只是爲了避免混淆(暫時遮蔽)內置功能。

+0

我不會使用'_open',因爲它將變量指定爲「受保護」。我認爲當你想避免關鍵字時(我會擴展以避免內建陰影),執行'open_'的習慣稍微習慣一些。否則,很好的答案(+1) – mgilson 2012-08-03 13:31:17

+0

這就是我正在考慮的慣例。我會更新。 – chepner 2012-08-03 13:32:42

+0

在這種情況下,由於變量被立即分配給實例屬性'self.open',所以*可能無關緊要。但是,我想即使是常規參數也可以用'argname = value'語法來調用,所以在這種情況下它會產生(小)差異。 – mgilson 2012-08-03 13:35:31

3

你都知道了吧,那open是內置的Python功能打開文件?也就是說,您正將一個method分配給一個變量。

+0

以及解釋#2!謝謝。它爲低價值如何工作? 如果我將'open'重新命名爲其他東西,是否是初始化其他變量的正確方法? – Joshua 2012-08-03 13:02:02

+0

@Joshua:不,它不是。看到我的答案爲什麼它不起作用。 – phant0m 2012-08-03 13:06:19

2

這不起作用。

對函數進行分析時,默認參數恰好爲。這意味着,它必須必須有一個值:方法簽名中的其他形式參數沒有值。他們更像是佔位符。因此,做你想做的事是不可能的。

Python將搜索名爲open先前存在的標識符,始終分配是非常反對執行功能時,它在那個時候你的變量highlow表示。

2

我不認爲你可以做到這一點。你有這樣的輸出,因爲「open」內置函數open()被考慮。如果不打電話打開你使用另一個名字,你會得到一個錯誤。

如果低,高,最後不能沒有你可以這樣做:

class Bar: 
def __init__(self, start, end, open, volume, high=None, low=None, last=None): 
    self.start = start 
    self.end = end 
    self.open = open 
    self.high = high if high is not None else open 
    self.low = low if low is not None else open 
    self.last = last if last is not None else open 
    self.volume = int(volume) 
1

在:

def __init__(self, start, end, open, volume, high=open, low=open, last=open) 

open指的是內置的open方法。將方法作爲參數傳遞在某些情況下非常有用,例如:預期可調用的max(sequence, key=itemgetter(2))

我懷疑你想預設highlowlast到是已傳遞給__init__的的open值,在這種情況下,我會使用關鍵字參數。

def __init__(self, start, end, open, volume, **kwargs): 
    for k in ('high', 'low', 'last'): 
     setattr(self, k, kwargs.get(k, open)) 

或者:

def __init__(self, start, end, open, volume, high=None, low=None, last=None): 
    if high is None: 
     self.high = open 
    # etc... 

我也不會用open作爲名稱...