Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python类的静态初始值设定项_Python_Python 3.x_Class_Static - Fatal编程技术网

Python类的静态初始值设定项

Python类的静态初始值设定项,python,python-3.x,class,static,Python,Python 3.x,Class,Static,我正在寻找Java中可以在Python类中使用的静态{…}块的等价物。具体来说,我希望能够访问静态资源,如类构造函数的参数,并将它们存储在类的字段中,如下所示: class A: constructor_args = A.__init__.__code__.co_varnames def __init__(self, foo=0, bar=1): ... 这个例子不起作用,因为当我调用A时,类A还没有初始化 我当前的解决方法是在创建类后更改静态字段,如下所示

我正在寻找Java中可以在Python类中使用的
静态{…}
块的等价物。具体来说,我希望能够访问静态资源,如类构造函数的参数,并将它们存储在类的字段中,如下所示:

class A:

    constructor_args = A.__init__.__code__.co_varnames

    def __init__(self, foo=0, bar=1):
        ...
这个例子不起作用,因为当我调用
A时,类A还没有初始化

我当前的解决方法是在创建类后更改静态字段,如下所示:

class A:

    constructor_args = ...

    def __init__(self, foo=0, bar=1):
        ...

constructor_args = A.__init__.__code__.co_varnames
但这个解决方案相当难看,因为我在类上下文之外更改了类的静态字段,如果该类包含大量代码,很容易忽略这里发生的事情


因此,基本上我需要一种在类初始化后立即调用函数的方法,并且我希望在类内部定义此函数。

您至少必须首先定义
\uuuuu init\uuuu
方法,但您可以在以下操作之后立即访问其属性:

class Foo:
    def __init__(self, bar, baz):
        pass

    constructor_args = __init__.__code__.co_varnames
类中
块代码在其自己的名称空间中执行,因此可以直接访问
\uuuuu init\uuuuu
,因为
\uuuuu init\uuuuu

可以使用:


相当于

class A:
    ...
A = store_constructor_args(A)

下面是一种简单的方法,它通过将需要完成的类移动到类主体中定义的函数中来延迟代码的执行。为了在使用后调用并删除该函数,我们定义了一个简单的装饰器:

import inspect

def finalizing(cls):
     cls.__finalize__(cls)
     del cls.__finalize__
     return cls

@finalizing
class example:
    def __finalize__(me):
        me.constructor_args = list(inspect.signature(me.__init__).parameters)
    def __init__(self, x):
        pass

example.constructor_args
# ['self', 'x']

话虽如此,我不确定你为什么不根据需要简单地执行
Foo.\uuu init\uuu….
,因为在类构造之前,
Foo
不能在函数之外访问。我的意思是,你存储的东西只是可以随时访问的东西的“别名”。在这种情况下是这样的。在我的实际代码中,我将对这些值应用一个转换,我将多次访问这些值,因此我希望在类初始化后立即存储此转换的结果。为什么要这样做?更好的解决方案是将这些值定义为类属性,将init默认值设置为None,然后仅在实际提供了参数的情况下设置实例变量。我不同意。至于我的示例代码:它实际上并不是关于访问
co_varnames
,特别是,这只是一个简单的问题,失败的原因与我的实际问题相同。顺便说一句
co_varnames
不仅提供参数,还提供函数体中定义的所有变量。如果需要参数,可以使用
inspect.signature
。我一点也不反对。相反,我认为应该明确定义“静态”(类级别)属性,而不是以编程方式。那么,您的解决方案是什么呢?我不想将
\uuuu init\uuuu
的参数列表的副本硬编码到静态属性中,因此我试图通过访问函数定义来创建副本。我不明白为什么我不应该以编程的方式解决这个问题。这还不错,但我仍然不喜欢在类上下文之外定义
defstore\u constructor\u args
class A:
    ...
A = store_constructor_args(A)
import inspect

def finalizing(cls):
     cls.__finalize__(cls)
     del cls.__finalize__
     return cls

@finalizing
class example:
    def __finalize__(me):
        me.constructor_args = list(inspect.signature(me.__init__).parameters)
    def __init__(self, x):
        pass

example.constructor_args
# ['self', 'x']