gpt4 book ai didi

python - 动态更改模块和类的定义,而不直接更改模块代码

转载 作者:太空宇宙 更新时间:2023-11-03 19:40:47 25 4
gpt4 key购买 nike

我什至不确定以下是否可行。我的问题很容易用以下代码描述。

我的模块定义为

asdf = 5
class MyClass:
def myfct(self):
return asdf

我有一个定义复杂类的模块。它使用其所在模块的定义。这里我称之为asdf。事实上,asdf 本身就是一个类定义,为了简单起见,我在这里只是将它作为一个整数。

我想将 asdf 作为成员从模块中删除,但仍然可以进行类(class)工作。因此,在从模块中删除它之前,我首先在加载模块后将其动态写入定义 MyClass 中,然后从模块中删除它。

import mymodule

MyClass.asdf = asdf
del sys.modules['mymodule'].asdf

最后我用它来实例化新类

myobj = mymodule.MyClass()
myobj.myfct()

但是当然,这会引发错误

NameError: name 'asdf' is not defined

如何在不更改类代码的情况下使类工作,即不将 return asdf 更改为 return self.asdf 但仍删除 asdf 来自模块(并且不添加其他模块属性)。但是,我可以在 import mymodule 之后动态更改函数。

请记住,函数定义非常复杂,因此不能使用 exec ( https://stackoverflow.com/a/11291851/4533188 ) 再次编写它。

我的一个想法是动态更改方法的签名,以便它接收可选参数 asdf。这样,里面的代码就会使用该变量,但我不知道该怎么做。 Byteplay/元类可能会有所帮助:

最佳答案

以下答案有效,但还算不错。基本上,我们将原始方法保存在虚拟变量myfct_original中。然后我们重新定义函数,将变量 MyClass.asdf 复制到模块中,应用原始方法,并将变量从模块中删除 - 因此在短时间内它可以在模块。

asdf = 5
class MyClass:
def myfct(self, test=1):
return asdf

MyClass.asdf = asdf
MyClass.myfct_original = MyClass.myfct

del sys.modules[__name__].asdf
delattr(MyClass, 'myfct')

def newmyfct(self, *args, **kwargs):
setattr(sys.modules[__name__], 'asdf', MyClass.asdf)
result = MyClass.myfct_original(self, *args, **kwargs)
del sys.modules[__name__].asdf
return result

setattr(MyClass, 'myfct', newmyfct)

myobj = MyClass()
myobj.myfct()

也许有人可以做得更好(见问题结尾)。

关于python - 动态更改模块和类的定义,而不直接更改模块代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60438977/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com