【问题标题】:settattr for parent class to use in childrensettattr 让父类在子类中使用
【发布时间】:2015-06-12 08:51:06
【问题描述】:

我有一个图书馆,有一个家长和十几个孩子:

# mylib1.py:
#
class Foo(object):
  def __init__(self, a):
    self.a = a


class FooChild(Foo):
  def __init__(self, a, b):
    super(FooChild, self).__init__(a)
    self.b = b

# more children here...

现在我想用一个简单的(但有点特别,用于另一种方法)方法来扩展该库。所以我想改变父类并使用它的孩子。

# 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. 这应该如何以更好的方式完成?

【问题讨论】:

  • 你想达到什么目的?为什么需要动态添加方法?
  • @Pynchia,我在问如何做得更好。所以我必须使用 mylib1.Fooall 它的子类,并且我需要在所有这些 [子] 类中使用 fooMethod。而且我不想继承所有内容。

标签: python parent-child parent setattr


【解决方案1】:

一种常见的方法是使用mixin

如果需要,您可以动态添加How do I dynamically add mixins as base classes without getting MRO errors?

【讨论】:

    【解决方案2】:

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

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

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

    有些人(例如 Brandon Craig-Rhodes)认为即使在测试中修补也很糟糕。

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

    【讨论】:

    • 我应该使用适当的mooMethod 创建class Moo 并从Moo 中的每个mylib1.* 子类化吗?像这样:class FooMoo(Foo, Moo) 然后class SubFooMoo(SubFoo, Moo) --- 并且对于来自mylib1的所有类都一样?
    • 我认为这个问题应该交给'said omar',因为他建议使用 mixin 方法。我的建议是创建一个通用的 fooMethod ,它可以根据某些属性使用不同的词。但不知道,你的目的是什么,很难说什么是正确的方法。但是,您应该避免使用猴子补丁。
    猜你喜欢
    • 2015-11-20
    • 2014-03-02
    • 1970-01-01
    • 2022-07-28
    • 2011-10-09
    • 1970-01-01
    • 2019-12-28
    • 2018-04-27
    • 2021-09-21
    相关资源
    最近更新 更多