方法python的默认值

时间:2011-04-19 00:58:29

标签: python

有没有比使用inspect模块更简洁的方法来获取方法的默认值?我想这样做:

class C(object):
    def __init__(self,Type='generic',X=5,Y=500):
        defaults=getDefaults() #not sure about this line
        typeDefaults_X={'short':'1','long':'10'}
        typeDefaults_Y={'large':2000,'small':100}
        if X == defaults['X']: 
            X = typeDefaults_X.get(Type, defaults['X'])
        if Y == defaults['Y']: 
            Y = typeDefaults_Y.get(Type, defaults['Y'])

我知道我可以通过以下方式做到这一点:

defaults=dict(zip(inspect.getargspec(C.__init__).args[1:],inspect.getargspec(C.__init__).defaults))

但它看起来非常恐怖。

2 个答案:

答案 0 :(得分:1)

我不清楚你要做什么。但是在该方法中,变量已经具有指定的默认值。但在我看来,在这种情况下你最好不要使用正式的默认参数。

class C(object):

    def __init__(self, Type='generic', X=None, Y=None):
        X = X or 5
        Y = Y or 500
        self.X, self.Y = {
            "generic": (X, Y),
            "short": (1, Y),
            "long": (10, Y),
            "large": (X, 2000),
            "small": (X, 100),
        }[Type]

    def __str__(self):
        return "X={0} Y={1}".format(self.X, self.Y)


print(C())
print(C('short'))
print(C('long'))
print(C('large'))
print(C('small'))
print(C('small', 10))
print(C('small', 20, 20))

我认为更清楚,但即使这样也有点难以理解。您可以重新考虑您的界面。

答案 1 :(得分:0)

它实际上比你想象的要差一些。 Python区分具有默认值的位置arg和仅含关键字的arg。您的代码不仅在您没有默认值作为第二个或第三个参数的情况下失败,而且如果您有可变长度* args关键字也会失败。您还应该使用inspect.getfullargspec。

但是,根据help(inspect.getfullargspec),spec.defaults始终是spec.args的最后一个元素。因此,您可以这样做:

import inspect
def getDefaults(func):
    spec = inspect.getfullargspec(func)
    numDefaults = len(spec.defaults)
    return dict(zip(spec.args[-numDefaults:], spec.defaults), **spec.kwonlydefaults)

基本上,这正是你所做的,但更为笼统。

没有更好的方法。 (好吧,你可以使用func.__defaultsfunc.__kwdefaults__func.__code__.co_*,但这些都是真正的hackish,似乎是一种内部。检查是正确的方法。)