条件继承忽略 python 中工作区中的更改条件
Conditional Inheritance neglects changed condition in workspace in python
我有两个 class 结构相似但功能不同的。我希望第三个 class 能够根据我的需要从其中任何一个继承。假设我有一个 objects 模块,并且我在模块中定义了 classes A、B 和 C。这是我在互联网上找到的语法后进行条件继承的方式:
cond = True
class C(A if cond else B):
def __init__(self):
super.__init__()
其中 A 和 B 是模块 objects 中的其他 class。现在,当我将 objects 和 class C 从 objects 模块导入 jupyter notebook 并更改 cond
:
objects.cond = False
my_class = C()
当我检查 parent class 的名称时,似乎没有任何效果。这意味着在更改条件后,我希望 class C 继承自 B,但它继承自 class A,就好像 cond
仍然计算为 True
。我试过不从模块中导入 class 而只是导入 objects 模块并用 my_class = objects.C()
实例化我的 class 但仍然不会发出新条件。
现在,在我的情况下,只要需要,只要在模块内手动更改条件并不困难,但我想知道所有这些都说明了 python 的语法。我是在做错什么,还是因为模块和 python 中的 class 级别之间存在某种命令优先级?或者语法可能有误?
N.B。我还没有写完整的 class C,其他的东西正在 class C 中完成,其中一些会根据 parent 被继承而改变。该代码用作虚拟但 IMO 足够的示例。
说明
Python 导入工作如下:
- 它执行模块中的代码
- 执行模块代码创建的符号放在模块符号table中(包括classC)
- import 只为一个进程加载一次模块(即模块是缓存)。因此,同一模块的后续导入无效。
- 因此,class C 的定义在第一次导入时放在模块符号 table 中。因此,在导入后更改条件对定义没有影响。
- 使用 reload 强制重新加载模块(即不使用缓存版本)。
跨模块共享全局变量
- 建议的方法是将全局共享变量放在配置模块中
考虑到以上内容,以下代码有效。
代码
config.py(包含跨模块共享的全局变量)
cond = True
test_abc.py(包含classes a,b,c的定义)
import config
class A():
def __init__(self, x):
self.x = x
def getX(self):
return f"A {self.x}"
class B():
def __init__(self, x):
self.x = x
def getX(self):
return f"B {self.x}"
# inherits from A or B
class C(A if config.cond else B):
def __init__(self, x):
super().__init__(x)
main.py(主程序)
from importlib import reload # Allows reloading of modules
import config # place variables we want to share across modules
# Test with cond = True
config.cond = True # Use True in condition for inheritance
import test_abc # Use import first time, can reload on subsequent calls
ca = test_abc.C(1)
print("First call: ", ca.getX()) # Test that we obtain A object
# Test with cond = False
config.cond = False
reload(test_abc) # reload module
ca = test_abc.C(1)
print("Second call:", ca.getX()) # Test that we obtained B object
输出
First call: A 1
Second call: B 1
我有两个 class 结构相似但功能不同的。我希望第三个 class 能够根据我的需要从其中任何一个继承。假设我有一个 objects 模块,并且我在模块中定义了 classes A、B 和 C。这是我在互联网上找到的语法后进行条件继承的方式:
cond = True
class C(A if cond else B):
def __init__(self):
super.__init__()
其中 A 和 B 是模块 objects 中的其他 class。现在,当我将 objects 和 class C 从 objects 模块导入 jupyter notebook 并更改 cond
:
objects.cond = False
my_class = C()
当我检查 parent class 的名称时,似乎没有任何效果。这意味着在更改条件后,我希望 class C 继承自 B,但它继承自 class A,就好像 cond
仍然计算为 True
。我试过不从模块中导入 class 而只是导入 objects 模块并用 my_class = objects.C()
实例化我的 class 但仍然不会发出新条件。
现在,在我的情况下,只要需要,只要在模块内手动更改条件并不困难,但我想知道所有这些都说明了 python 的语法。我是在做错什么,还是因为模块和 python 中的 class 级别之间存在某种命令优先级?或者语法可能有误?
N.B。我还没有写完整的 class C,其他的东西正在 class C 中完成,其中一些会根据 parent 被继承而改变。该代码用作虚拟但 IMO 足够的示例。
说明
Python 导入工作如下:
- 它执行模块中的代码
- 执行模块代码创建的符号放在模块符号table中(包括classC)
- import 只为一个进程加载一次模块(即模块是缓存)。因此,同一模块的后续导入无效。
- 因此,class C 的定义在第一次导入时放在模块符号 table 中。因此,在导入后更改条件对定义没有影响。
- 使用 reload 强制重新加载模块(即不使用缓存版本)。
跨模块共享全局变量
- 建议的方法是将全局共享变量放在配置模块中
考虑到以上内容,以下代码有效。
代码
config.py(包含跨模块共享的全局变量)
cond = True
test_abc.py(包含classes a,b,c的定义)
import config
class A():
def __init__(self, x):
self.x = x
def getX(self):
return f"A {self.x}"
class B():
def __init__(self, x):
self.x = x
def getX(self):
return f"B {self.x}"
# inherits from A or B
class C(A if config.cond else B):
def __init__(self, x):
super().__init__(x)
main.py(主程序)
from importlib import reload # Allows reloading of modules
import config # place variables we want to share across modules
# Test with cond = True
config.cond = True # Use True in condition for inheritance
import test_abc # Use import first time, can reload on subsequent calls
ca = test_abc.C(1)
print("First call: ", ca.getX()) # Test that we obtain A object
# Test with cond = False
config.cond = False
reload(test_abc) # reload module
ca = test_abc.C(1)
print("Second call:", ca.getX()) # Test that we obtained B object
输出
First call: A 1
Second call: B 1