从内部类访问外部类方法

时间:2010-07-01 18:54:55

标签: python

我想要一个具有嵌套类的python类,其中内部类可以访问外部类的成员。我知道正常的嵌套甚至不要求外部类有一个实例。我有一些代码似乎产生了我想要的结果,我想要关于风格和不可预见的并发症的反馈

代码:

class A():

    def __init__(self,x):
        self.x = x
        self.B = self.classBdef()

    def classBdef(self):
        parent = self

        class B():
            def out(self):
                print parent.x

        return B

输出:

>>> a = A(5)
>>> b = a.B()
>>> b.out()
5
>>> a.x = 7
>>> b.out()
7

所以,A有一个内部类B,它只能从A的实例创建。然后B可以通过父变量访问A的所有成员。

2 个答案:

答案 0 :(得分:2)

这对我来说看起来不太好。 classBdef是类工厂方法。通常(并且很少)您将使用这些来创建自定义类,例如具有自定义超类的类:

def class_factory(superclass):
    class CustomClass(superclass):
        def custom_method(self):
            pass
    return CustomClass

但是你的构造没有使用自定义。事实上,它将A的东西放入B中并将它们紧密地耦合在一起。如果B需要知道一些A变量,那么使用参数进行方法调用,或者使用对A对象的引用来实例化B对象。

除非您需要解决特定的原因或问题,否则只需制作一个普通的工厂方法,在A中提供B对象而不是b = a.B()之类的东西就会容易得多。

class B(object):
    def __init__(self, a):
        self.a = a

    def out(self):
        print self.a.x

class A(object):
    def __init__(self,x):
        self.x = x

    def create_b(self):
        return B(self)

a = A()
b = a.create_b()
b.out()

答案 1 :(得分:0)

我不认为你想要做的是一个非常好的主意。如果你懒得在另一个内部定义一个内部类,那么python中的“内部”类与它们的“外部”类绝对没有特殊关系。这完全相同:

class A(object):
    class B(object):
        pass

就是说:

class B(object): pass
class A(object): pass
A.B = B
del B

也就是说,通过在其元类上定义__get__(),可以将“内部”类转换为描述符,从而实现类似于您所描述的内容。我建议不要这样做 - 它太复杂了,收效甚微。

class ParentBindingType(type):
    def __get__(cls, inst, instcls):
        return type(cls.__name__, (cls,), {'parent': inst})
    def __repr__(cls):
        return "<class '%s.%s' parent=%r>" % (cls.__module__, 
            cls.__name__, getattr(cls, 'parent', None))

class B(object):
    __metaclass__ = ParentBindingType
    def out(self):
        print self.parent.x

class A(object):
    _B = B
    def __init__(self,x):
        self.x = x
        self.B = self._B

a = A(5)
print a.B
b = a.B()
b.out()
a.x = 7
b.out()

打印:

<class '__main__.B' parent=<__main__.A object at 0x85c90>>
5
7