2012-08-03 184 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作为名称...