从内部类访问外部类的方法
我想要一个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类,这个B类只能通过A类的实例来创建。然后,B类可以通过一个叫做parent的变量访问A类的所有成员。
2 个回答
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
2
我觉得这个看起来不太好。classBdef
是一个类工厂方法。通常情况下(而且很少用到),你会用它来创建自定义类,比如说一个有自定义父类的类:
def class_factory(superclass):
class CustomClass(superclass):
def custom_method(self):
pass
return CustomClass
但是你的构造方式并没有利用到这种自定义。实际上,它把 A 的东西放到了 B 里,并且把它们紧密地耦合在一起。如果 B 需要知道某个 A 的变量,那就应该通过方法调用并传递参数,或者在创建 B 对象的时候传入 A 对象的引用。
除非你有特定的理由或者需要解决的问题,否则直接做一个普通的工厂方法,在 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()