0

我有一个这样的代码片段

class A(object):
    class b:
        def print_hello(self):
            print "Hello world"
    b = property(b)

而且我想覆盖内部类b(请不要担心小写名称)行为。比如说,我想添加一个新方法或者我想更改现有方法,例如:

class C(A):
    class b(A.b):
        def print_hello(self):
            print "Inner Class: Hello world"
    b = property(b)

现在,如果我将C's 对象创建为c = C(),并调用c.b我得到TypeError: 'property' object is not callable error. 我将如何通过这个和print_hello扩展内部类的调用?免责声明:我不想更改A课程代码。

更新:基类“A”试图模拟我在其中一个开源 api 中看到的类。所以这就是为什么我不想更改核心 api,而是根据我自己的要求对其进行扩展。

4

3 回答 3

1

我不太确定为什么要将内部类定义为外部类的属性。(我不是 Python 专家,所以也许有一个我不知道的原因)。

如果没有以下属性,它似乎可以正常工作:

class A(object):
    class b:
        def print_hello(self):
            print "A Hello world"

class C(A):
    class b(A.b):
        def print_hello(self):
            print "C Hello world"


outer = C()
inner = outer.b()
inner.print_hello() # prints "C Hello world"
于 2010-04-23T08:17:39.800 回答
1

这失败的原因是由于b = property(b)行 Ab 不是您定义的类,而是一个属性对象。我实际上有点惊讶它在创建类时没有失败。A.b.fget如果您用作基类,它将起作用。但正确的答案是:不要那样做。Python 没有任何常规意义上的内部类,在类定义范围内定义的类与常规类没有什么不同。事实上,这段代码具有完全相同的最终结果:

class A(object):
    pass

class b(object):
    def print_hello(self):
        print("Hello world")

A.b = property(b)

我不确定您要达到的目标到底是什么。如果我理解正确,您有一个父类,该类具有返回另一个类的实例的属性,并且您希望拥有一个具有返回另一个类的子类实例的属性的子类。要对返回的类进行子类化,您需要获取对该类的引用以将其用作基础。然后,您可以重写该属性以返回子类的实例。如果您使用从实例中查找类的属性,则实际上不需要覆盖属性定义:

class A(object):
    class B(object):
        def print_hello(self):
            print("Hello from A.B")
    b = property(lambda self: self.B())

class C(A):
    class B(A.B):
       def print_hello(self):
           print("Hello from C.B")

A().b.print_hello()
C().b.print_hello()
于 2010-04-23T09:01:43.937 回答
0

每当您访问 A 的“b”属性时,对 A 实例的引用都会传递给 getter - 然后将其作为参数传递给 b 的构造函数。这从一开始就破坏了您的构造,因为 b 的(默认)构造函数不采用任何额外的参数。

看起来您的 C 类不起作用,因为它的内部“b”类继承自 A 的“b”属性对象。

我很好奇你为什么要在这里买房——它只会让事情变得复杂。事实上,删除它可以让您在每个实例的基础上用另一个类替换 A 的内部“b”类,而根本不必求助于继承。您能否给我们一些更多的信息来处理,例如这个结构背后的意图和目的?

于 2010-04-23T08:55:58.987 回答