我有一个要在运行时填充的类属性,但是我不想传递该值。我现在正在做的是:
weird_class.py
class WeirdClass:
prop = NotImplementedError
runtime_file.py
from weird_class import WeirdClass
PROP = 'somevalue'
class WeirdClassChild(WeirdClass):
prop = PROP
这可行,但是每当我创建WeirdClassChild
时,都必须设置prop
值,这很烦人。
我想让WeirdClassChild
自动选择PROP全局变量,而无需我特别告知它。
我想做类似的事情:
class WeirdClass:
prop = __global_namespace__.PROP
这在python中可能吗?
答案 0 :(得分:2)
您可以使用inspect
ion来确定实例化您的类的上下文:
# class definition
import inspect
class Weird:
def __init__(self):
caller_frame = inspect.stack()[1]
caller_module = caller_frame[0]
self.prop = caller_module.f_globals['PROP']
# instantiation
PROP = 555
x = Weird()
print(x.prop)
=> 555
我不一定会推荐它,但是如果您有充分的理由这样做...
答案 1 :(得分:1)
您也许可以使用元类:
#!/usr/bin/env python3
PROP = "only for subclasses"
class _WierdMeta(type):
# Not sure if you should use __init__ or __new__
# Use one or the other.
# `cls` is an instance of the class type that _WierdMeta creates
def __init__(cls, name, bases, dct):
if bases:
cls.prop = PROP
super().__init__(name, bases, dct)
# `cls` is _WierdMeta
def __new__(cls, name, bases, dct):
class_type = super().__new__(cls, name, bases, dct)
if bases:
class_type.prop = PROP
# this return value will be the `cls` passed to __init__ above
return class_type
class WierdBase(metaclass=_WierdMeta):
"""Base class."""
prop = "base"
class WierdChild(WierdBase):
pass
wb = WierdBase()
wc = WierdChild()
print(wb.prop) # print('base')
print(wc.prop) # print('only for subclasses')
似乎从Python 3.6开始,您可以使用__init_subclass__
来做到这一点。
class WierdBase():
"""Base class."""
prop = "base"
# I'm not 100% on the args here...
def __init_subclass__(cls, **kwargs):
# ... or here.
super().__init_subclass__(**kwargs)
if cls is not WierdBase:
cls.prop = PROP
答案 2 :(得分:1)
根据您最后的用法说明,为什么不添加另一个基类?
from weird_class import WeirdClass
PROP = 'somevalue'
class WeirdClassChildBase(WeirdClass):
prop = PROP
class WeirdClassChild_1(WeirdClassChildBase):
pass
class WeirdClassChild_2(WeirdClassChildBase):
pass
...
答案 3 :(得分:0)
我将其分为三个文件,并按照此处说明的方法进行操作:https://instructobit.com/tutorial/108/How-to-share-global-variables-between-files-in-Python:
globals.py
-在这里初始化PROP的值weird_class.py
-在这里,您应该导入globals.py并使用PROP值start.py
-在这里您可以测试奇怪的类,但是在导入其模块之前,您应该导入globals.py
并调用一些初始化方法 globals.py
文件将汇总所有全局默认值。首先假设在start.py
脚本中,您应该导入全局变量并对其进行初始化。
import globals
globals.initialize()
from weird_class import WeirdClass
c = WeirdClass()
print(c.prop)
在weird_class文件中,如果已导入变量,则可以从globals.py
访问变量:
import globals
class WeirdClass:
prop = globals.PROP
最后globals.py
看起来像这样:
def initialize():
global PROP
PROP = "my global value"
此处的关键部分是在设置初始值之前声明global PROP
。 global
关键字将在模块global
中使变量globals
。
在模块范围内的单个中心位置具有全局变量,常量和所有魔术值通常是一个优势。