Python 覆盖导入的类
是否可以覆盖类的定义,以便所有调用(在我的程序或其他.py文件中)都接收覆盖?例如:Python 覆盖导入的类,python,python-3.x,inheritance,Python,Python 3.x,Inheritance,是否可以覆盖类的定义,以便所有调用(在我的程序或其他.py文件中)都接收覆盖?例如: # package.py class orgClass: def some_method(x): return x * x # my_prog.py import other_package from package import orgClass class orgClass(orgClass): def some_method(x): return x +
# package.py
class orgClass:
def some_method(x):
return x * x
# my_prog.py
import other_package
from package import orgClass
class orgClass(orgClass):
def some_method(x):
return x + x
if __name__ == '__main__':
other_package.run()
# other_package.py
from package import orgClass
def run():
o = orgClass()
x = 5
print (o.some_method(x)) # would print 10 not 25; however it prints 25
我需要为这个特定的程序更改
orgClass
的实现,但我不想更改源代码(原始软件包的;无论如何,这似乎是个坏主意),所以我想我可以“重写”my_prog.py
中的类实现,如果我理解正确,那么它将影响来自\uu主线程的所有调用
1) 导入orgClass
2) 调整等级
#my_classes.py
import orgClass
class orgClass(orgClass):
def some_method(x):
return x+x
编辑:
要使用此函数,请使用
from my_classes import orgClass
编辑:
现在我看到您的导入是不同的,那么可以使用如下参数完成导入:
# package.py
class orgClass:
def some_method(x):
return x * x
# my_prog.py
import other_package
from package import orgClass
class orgClass(orgClass):
def some_method(x):
return x + x
if __name__ == '__main__':
other_package.run(orgClass)
# other_package.py
def run(o):
x = 5
print (o.some_method(x)) # would print 10 not 25; however it prints 25
据我所知,您有两种选择:
编辑原始文件package.py
使每个需要新方法的文件导入my_prog.py
因为您不想要第一个选项,所以答案是否定的-您不能这样做。您在这里有几个选项
备选案文1。您可以直接修改类对象(猴子补丁):
(这方面的变体包括猴子修补整个orgClass
对象,效果类似。)
备选案文2。您可以创建一个替换模块,然后修改sys.path
以强制首先加载它:
# replacement-packages/package.py
class orgClass:
def some_method(self, x):
return x + x
# my_prog.py
sys.path = ['path/to/replacement-packages'] + sys.path
import package # loads replacement-packages/package.py
(这方面的变体包括在中使用路径文件或各种垫片,或直接修改系统模块
备选案文3。您可以将整个包
项目分叉,并对其进行修改以满足您的需要。然后,您可以使用或其他设置仅将修改后的软件包作为my_prog
程序的依赖项安装,而其他程序将使用默认的python
解释器,该解释器将加载原始包。您可以从my_prog
@internetu用户导入orgClass
,这需要我修改源代码。我想要覆盖的类来自一个库(不是我开发的)。我只需要覆盖此实例的函数,但是我希望调用该类的所有其他.py文件接收在my_prog.py
中定义的更新。您可以在包
模块中对该类进行猴子补丁,方法是直接修改类对象,或者在sys.modules
中修改模块对象。只有在相关代码导入之前应用monkey补丁,这才有效。最有可能的是,仅仅修改代码将是最好的途径:它更简单,更容易调试,并且不太可能在程序的其他地方引入细微的错误。请注意,如果它是一个开源库,您可以通过任何需要的修改创建自己的库分支。(如果库不是开源的,无论你做什么来解决这个问题,你可能都需要和律师谈谈。)@DanielPryden虽然我同意修改原始代码,但更改只适用于这个程序;不希望其他程序(为其他用途引用同一类的程序)也得到更改(如果我修改了源文件,它们也会得到更改)。在my_prog.py
中,我导入要覆盖的类。但是在其他.py
文件中,它们可能会调用orgClass
,但它们调用的是原始版本,而不是我的覆盖版本。我已经完成了您在此处显示的操作,但是更改不会生效,因为其他.py
文件不会导入我的程序来接收更新的类。我需要在原始文件中覆盖原始类。您必须调用my_classes.py
,否则无法完成。在导入orgClass
和如果您不提供它(例如我的答案,更改导入)使用它之间没有链接到您的更改。我不想修改原始库以从my_prog import orgClass调用。我只是想暂时覆盖这个程序的函数,不去管源代码文件。如果我不能做到这一点,那么问题的答案是否定的。唯一这样做的方法是在定义类之后重新定义库中的类,例如类orgClass():def some_method()
(…code…类orgClass)(orgClass):def some_method(x):
(…code…)
# replacement-packages/package.py
class orgClass:
def some_method(self, x):
return x + x
# my_prog.py
sys.path = ['path/to/replacement-packages'] + sys.path
import package # loads replacement-packages/package.py