猿问

自动初始化实例变量?

我有一个看起来像这样的python类:


class Process:

    def __init__(self, PID, PPID, cmd, FDs, reachable, user):

其次是:


        self.PID=PID

        self.PPID=PPID

        self.cmd=cmd

        ...

有没有办法自动初始化这些实例变量,例如C ++的初始化列表?它将节省大量冗余代码。


天涯尽头无女友
浏览 548回答 3
3回答

POPMUISE

您可以使用装饰器:from functools import wrapsimport inspectdef initializer(func):    """    Automatically assigns the parameters.    >>> class process:    ...     @initializer    ...     def __init__(self, cmd, reachable=False, user='root'):    ...         pass    >>> p = process('halt', True)    >>> p.cmd, p.reachable, p.user    ('halt', True, 'root')    """    names, varargs, keywords, defaults = inspect.getargspec(func)    @wraps(func)    def wrapper(self, *args, **kargs):        for name, arg in list(zip(names[1:], args)) + list(kargs.items()):            setattr(self, name, arg)        for name, default in zip(reversed(names), reversed(defaults)):            if not hasattr(self, name):                setattr(self, name, default)        func(self, *args, **kargs)    return wrapper用它来装饰__init__方法:class process:    @initializer    def __init__(self, PID, PPID, cmd, FDs, reachable, user):        pass输出:>>> c = process(1, 2, 3, 4, 5, 6)>>> c.PID1>>> dir(c)['FDs', 'PID', 'PPID', '__doc__', '__init__', '__module__', 'cmd', 'reachable', 'user'

蝴蝶不菲

如果您使用的是Python 2.6或更高版本,则可以使用collections.namedtuple:>>> from collections import namedtuple>>> Process = namedtuple('Process', 'PID PPID cmd')>>> proc = Process(1, 2, 3)>>> proc.PID1>>> proc.PPID2当您的班级实际上只是一大包价值观时,这尤其合适。

DIEA

对于Python 3.7+,您可以使用Data Class,这是一种非常Python化且可维护的方式来完成您想要的事情。它允许您为类定义字段,它们是自动初始化的实例变量。它看起来像这样:@dataclassclass Process:    PID: int    PPID: int    cmd: str    ...该__init__方法将已经在您的班级中。请注意,这里需要类型提示,这就是我在示例中使用int和的原因str。如果您不知道字段的类型,则可以使用模块中的任何typing。与建议的解决方案相比,数据类具有许多优点:它是明确的:所有字段都是可见的,这尊重Python的Zen并使其可读和可维护。将其与的使用进行比较**kwargs。它可以有方法。就像其他任何课程一样。它使您可以超越自动__init__使用__post_init__方法。
随时随地看视频慕课网APP

相关分类

AngularJS
我要回答