Python 2.7覆盖了不同模块中的整个类定义

时间:2015-04-08 08:42:34

标签: python

我想覆盖类的功能(安装在系统目录中)

module a
class A:
   ...

with(my local class)

module b
class B:
   ...

完全是,它覆盖了ABBclass A中常见的所有方法。有类似的问题

Python - how can I override the functionality of a class before it's imported by a different module?

但是它们会覆盖一个(或几个方法)。

Q1:我想我可以查看class B的所有方法并找到module a中的对应方,但是有更简洁的方法吗?

我尝试覆盖整个类定义到目前为止还没有成功,所以要么我没有正确地执行它,要么这是不可能的。

Q2:我认为在任何其他模块尝试导入from a import A之前必须进行覆盖?

为什么我这样做

我需要在代码中改变A类实例的行为,这是我无法轻易改变的

设置

我有一堆模块A(我不能轻易改变)以及稍后调用#module c from a import A a_instance_global = A() def some_function() a_instance = a() a_instance.somemethod() 的方法:

A

在每一个中,我都想用B模拟#module d (module that I can change) from c import some_function # I would like to say something like a.A = b.B # which works, however the override stays valid only in module d # and I would like to have the override to work in module c some_function() a_instance_global.call_something() some_other_function(a_instance_global): ... 而不更改已安装模块的代码。

{{1}}

3 个答案:

答案 0 :(得分:4)

简单方法:

import a
class A: # replacement A
    ...

a.A = A

这里唯一需要注意的是,在任何其他模块创建A的实例之前,您必须执行此覆盖;否则,这些实例将引用旧的类定义。

如果在创建实例之前无法进行此替换,则您必须自行解决每个类方法的修补问题。

答案 1 :(得分:2)

如果我的问题正确,那么情景就是

file - > A_module.py(原文A类在这里)

class A(object):
    def one(self):
        print "A -> one"
    def two(self):
        print "A -> two"
    def three(self):
        print "A -> three"

file - > module_where_a_is_used.py(您希望在此处进行更改。)

from A_module import A

def lol_function():
    a_object = A()
    a_object.three()
    a_object.one()

解决方案是,制作模块 - > A_module_class_modifier.py 从this

中提出一个想法(而不是复制:P)
import A_module
from A_module import A

class B(A):
    def one(self):
        print "B -> one"
    def two(self):
        print "B -> two"

A_module.A = B

现在,您的module_where_a_is_used.py应该完好无损(A.K.A. C模块),

from A_module import A

def lol_function():
    a_object = A()
    a_object.three()
    a_object.one()

lol.py

import A_module_class_modifier
from module_where_a_is_used import lol_function

lol_function()

运行lol.py后的结果

I have no name!@sla-334:~/stack_o/stack_o_class$ python lol.py 
A -> three
B -> one

我希望,我说得对,如果不是,请告诉我,我做错了什么。

答案 2 :(得分:1)

对于Q2,是的,除非您找到导入A之后创建的该类的所有实例(但在更改A之前),否则我认为除此之外没有办法解决问题在aB并更新它们。

对于Q1,导入sys并插入模块b代替a的脏方法:

import sys
sys.modules['a'] = sys.modules['b']

在执行完之后,任何导入或反对“' a'将有效地b。如果另外在b中你有:

A = B

然后创建类A的实例将有效地创建B这适用于在sys.modules行执行后创建的所有实例,无论是否导入模块{{1在那之前或之后。