【问题标题】:Python inheritance in dynamically created classes动态创建的类中的 Python 继承
【发布时间】:2012-09-13 22:27:15
【问题描述】:

我正在尝试使用元类来实现以下功能:

class foo( object ):

    def __init__( self ):
        self.val = 'foo'

    def bar( self ):
        print 'hello world'
        print self.val

f = foo()
f.bar() #prints 'hello world' followed by foo

def newbar( self ):
    super( **?**, self).bar()
    print 'another world!'

fooNew = type('fooNew', (foo,), {'bar':newbar})
n = fooNew()
n.bar() # should print everything in f.bar() followed by 'another world!'

我知道我可以使用猴子补丁来实现我自己的函数 newbar。但是有一个细微的区别,我希望新的 bar 函数首先运行基类 bar 函数,然后才运行任何附加功能。

我该怎么做?或者我怎样才能做得更好?

【问题讨论】:

  • 这个问题与元类有什么关系?
  • fooNew 是使用元类类型创建的?我是元类新手,可能是错的
  • 是的,type 是标准的内置元类。如果人们说“使用元类”,他们通常指的是定义 custom 元类。你在这里所做的只是使用一种相当不方便的方式来动态创建一个类。
  • 谢谢斯文。创建此类的更好方法是什么?
  • 我用一种方式更新了我的答案。

标签: python metaclass monkeypatching


【解决方案1】:

使用super() 调用基类方法在某些多重继承情况下具有优势,但在大多数其他情况下(即在 95% 的用例中)存在劣势。所以这里干脆不要使用super(),而是直接调用基类方法。

我会采用另一种方式(前提是我确定我真的想动态创建一个类)。您可以在函数中定义整个类并返回它:

def class_factory():
    class NewFoo(foo):
        def bar(self):
            foo.bar()
            print 'another world!'
    return NewFoo

【讨论】:

    【解决方案2】:

    您可以更改newbar 的定义以返回一个函数:

    def newbar_factory(cls):
        def newbar(self):
            super(cls, self).bar()
            # Alternately, as Sven points out you could do
            # cls.bar(self)
            print "another world!"
    
        return newbar
    
    # Use
    fooNew = type('fooNew', (foo,), {'bar':newbar_factory(foo)})
    

    可能有更好的方法来完成您正在尝试做的事情 - 但这应该解决问题。

    【讨论】:

    • newbar_factory 缺少 return newbar
    • 我对这件事有点担心,并同意这是要走的路。
    猜你喜欢
    • 1970-01-01
    • 2018-03-10
    • 2011-12-28
    • 1970-01-01
    • 2014-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多