python: __init__ 模板

0 投票
2 回答
709 浏览
提问于 2025-04-16 10:55

我发现我经常写下面的代码:

class X:
  def __init__(self, var1, var2, var3):
    self.var1 = var1
    self.var2 = var2
    self.var3 = var3
    # more code here

我在想,做一个可以重复使用的模板是不是个好主意?这样就不用每次都写一样的代码了。如果是的话,我该怎么做呢?

2 个回答

0

你可以写一个包装器,来分析名字并为 self 创建属性。但是,这真的有必要吗?我的意思是,这样的代码会比这多得多。如果你的构造函数参数太多了,或许把它重构成更合理的形式会更好?

另外,如果你希望其他人能参与你的项目,那就给装饰器起个名字,比如 @magic_you_should_really_read_about,或者干脆写一些标准的代码 ;) 从“导入这个”中可以看到:明确比隐含要好。

1

我不建议在正式的代码中使用这样的模板,因为

Explicit is better than implicit.

对于一些临时的原型来说,这可能是可以接受的。这里有一个来自Python示例的例子:

这个例子定义了一个装饰器,可以附加到__init__方法上:

def injectArguments(inFunction):
    """
    This function allows to reduce code for initialization 
    of parameters of a method through the @-notation
    You need to call this function before the method in this way: 
    @injectArguments
    """
    def outFunction(*args, **kwargs):
        _self = args[0]
        _self.__dict__.update(kwargs)
        # Get all of argument's names of the inFunction
        _total_names = \
            inFunction.func_code.co_varnames[1:inFunction.func_code.co_argcount]
        # Get all of the values
        _values = args[1:]
        # Get only the names that don't belong to kwargs
        _names = [n for n in _total_names if not kwargs.has_key(n)]

        # Match names with values and update __dict__
        d={}
        for n, v in zip(_names,_values):
            d[n] = v
        _self.__dict__.update(d)
        inFunction(*args,**kwargs)

    return outFunction

一个测试:

class Test:
    @injectArguments
    def __init__(self, name, surname):
        pass

if __name__=='__main__':
    t = Test('mickey', surname='mouse')
    print t.name, t.surname

撰写回答