2015-06-12 136 views
1

我有一个父一个图书馆和儿童十几使用另一种方法)的方法。所以我想改变父类并使用它的孩子。settattr对父类儿童

# mylib2.py: 
# 
import mylib1 

def fooMethod(self): 
    print 'a={}, b={}'.format(self.a, self.b) 

setattr(mylib1.Foo, 'fooMethod', fooMethod) 

现在我可以这样使用它:

# way ONE: 
import mylib2 

fc = mylib2.mylib1.FooChild(3, 4) 
fc.fooMethod() 

或像这样:

# way TWO: 
# order doesn't matter here: 
import mylib1 
import mylib2 

fc = mylib1.FooChild(3, 4) 

fc.fooMethod() 

所以,我的问题是:

  1. 这是好事?
  2. 这应该如何更好地完成?
+0

你想达到什么目的?为什么你需要动态添加一个方法? – Pynchia

+0

@Pynchia,我在问如何做得更好。所以我必须使用'mylib1.Foo'和* all *它的子类,并且我需要在所有这些[sub]类中都有'fooMethod'。我不想将所有东西都划分子类。 – brownian

回答

0

编程中有一个通用规则,即应该避免依赖全局状态。换句话说,这意味着你的全局变量应该是可能的。类(大部分)是全局的。

你的方法被称为猴子修补。如果你没有真正的理由来解释它,你应该避免它。这是因为猴子补丁违反了上述规则。

想象一下你有两个独立的模块,他们都使用这种方法。其中一个将Foo.fooMethod设置为某种方法。另一个 - 到另一个。然后你以某种方式在这些模块之间切换控制。结果将会是,很难确定在哪里使用fooMethod。这意味着难以调试问题。

有些人(比如Brandon Craig-Rhodes),即使在测试中也认为补丁不好。

我会建议的是使用一些属性,当你实例化你的Foo()类的实例(及其子)时,它将控制你的fooMethod的行为。那么这个方法的行为将取决于你如何实例化对象,而不是全局状态。

+0

我应该使用适当的'mooMethod'和'moo'中的每个'mylib1。*'创建'class Moo'吗?像这样:'class FooMoo(Foo,Moo)'然后'class SubFooMoo(SubFoo,Moo)'---和'mylib1'中的所有类都一样吗? – brownian

+1

我认为这个问题应该去'奥马尔说',因为他建议mixin方法。我的建议是创建一个通用的fooMethod,根据某些属性可以用不同的词语。但不知道,你的目的是什么,很难说什么是正确的方法。但是,你应该避免monkeypatching。 – zefciu