【问题标题】:Conditional Inheritance neglects changed condition in workspace in python条件继承忽略python工作区中的更改条件
【发布时间】:2021-08-17 09:10:53
【问题描述】:

我有两个结构相似但功能不同的类。我希望第三个类能够根据我的需要从其中任何一个继承。假设我有一个对象模块,并且在模块中定义了类 A、B 和 C。这是我在互联网上找到的语法后进行条件继承的方式:

cond = True

class C(A if cond else B):

    def __init__(self):
        super.__init__()

其中 A 和 B 是模块对象中的其他类。现在,当我将对象模块中的对象和 C 类导入 jupyter 笔记本并更改 cond:

objects.cond = False
my_class = C()

当我检查父类的名称时,似乎没有任何效果。这意味着在更改条件后,我希望类 C 继承自 B,但它从类 A 继承,就好像 cond 仍然评估为 True。我试过不从模块导入类,只导入对象模块并用my_class = objects.C() 实例化我的类,但仍然不会发出新条件。

现在在我的情况下,只要我需要在模块内手动更改条件并不困难,但我想知道所有这些对 python 语法的说明。我做错了什么还是因为python中模块和类级别之间的某种命令优先级?或者语法可能是错误的?

注意我还没有编写完整的 C 类,其他东西正在 C 类中完成,其中一些会根据继承的父级而改变。该代码用作虚拟但 IMO 足够的示例。

【问题讨论】:

  • 您是否尝试过在导入模块中只使用类 A 和 B 并在本地设置 cond 和定义 C?我认为这是您的条件继承所必需的,因为代码是在导入时执行的,即“诸如 class 和 def 之类的关键字不是声明。相反,它们是执行的实时语句”。
  • 好的,这是有道理的,我只是想知道在 python 的更深层次上发生了什么。我认为提供一个彻底解释您刚才评论的答案不会有害。
  • @P.basimfar——发布了答案。让我知道这是否有助于澄清。

标签: python oop multiple-inheritance


【解决方案1】:

说明

Python 导入工作如下:

  • 它执行模块中的代码
  • 执行模块代码创建的符号放在模块符号表中(包括C类)
  • import 只为一个进程加载一次模块(即模块是缓存的)。因此,同一模块的后续导入无效。
  • 因此,C 类的定义在第一次导入时被放置在模块符号表中。因此,在导入后更改 cond 不会影响定义。
  • 使用 reload 强制重新加载模块(即不使用缓存版本)。

跨模块共享全局变量

  • 建议的方法是将全局共享变量放在配置模块中

考虑到上述情况,以下代码有效。

代码

config.py(包含跨模块共享的全局变量)

cond = True

test_abc.py(包含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

【讨论】:

    猜你喜欢
    • 2020-06-19
    • 2021-04-22
    • 2022-12-09
    • 1970-01-01
    • 2021-09-27
    • 2011-01-27
    • 2021-11-18
    • 1970-01-01
    • 2022-03-22
    相关资源
    最近更新 更多