在 Python 中自省构造函数 __init__ 的参数

Introspecting arguments from the constructor function __init__ in Python

有什么方法可以在不创建新实例的情况下从 __init__ 中提取参数。 代码示例:

class Super:
    def __init__(self, name):
        self.name = name

我正在寻找类似 Super.__dict__.keys() 类型的解决方案。只是为了检索名称参数信息而不添加任何值。有这样的选择吗?

更新 Python 3.3+(正如 beeb 在评论中指出的那样)

您可以使用 Python 3.3 中引入的 inspect.signature:

class Super:
    def __init__(self, name, kwarg='default'):
        print('instantiated')
        self.name = name

>>> import inspect
>>> inspect.signature(Super.__init__)
<Signature (self, name, kwarg='default')>

原回答如下

您可以使用inspect

>>> import inspect
>>> inspect.getargspec(Super.__init__)
ArgSpec(args=['self', 'name'], varargs=None, keywords=None, defaults=None)
>>> 

编辑:inspect.getargspec 实际上并没有创建 Super 的实例,见下文:

import inspect

class Super:
    def __init__(self, name):
        print 'instantiated'
        self.name = name

print inspect.getargspec(Super.__init__)

这输出:

### Run test.a ###
ArgSpec(args=['self', 'name'], varargs=None, keywords=None, defaults=None)
>>> 

请注意,instantiated 从未打印过。

在 class 字段中存储具体 __init__ 参数的元class:

class ParameterReader(ABCMeta):
    def __init__(cls, *args, **kwargs):
        parameters = inspect.signature(cls.__init__).parameters
        parameters = {key: value for key, value in parameters.items() if key not in ['self', 'args', 'kwargs']}
        try:
            cls._init_parameters = cls.__bases__[0]._init_parameters.copy()
            cls._init_parameters.update(parameters)
        except AttributeError:
            cls._init_parameters = parameters

        super().__init__(*args, **kwargs)

_init_parameters 然后可以在 class 实例内部或外部使用:

class Fruit(metaclass=ParameterReader):
    def __init__(self, color):
        print(color)

class Corn(Fruit):
    def __init__(self, size, *args, **kwargs):
        super().__init__(*args, **kwargs)
        print(size)
        print(self._init_parameters)

print(Corn._init_parameters)

制作中:

{'color': <Parameter "color">, 'size': <Parameter "size">}

以及在实例化中:

Corn(10, 'yellow')

制作中:

yellow
10
{'color': <Parameter "color">, 'size': <Parameter "size">}

请注意在 Corn 的 __init__ 参数中使用 *args**kwargs 是如何处理的。


此外,请注意命名 difference between arguments and parameters