如何从内部类访问外部类?
我遇到了这样的情况……
class Outer(object):
def some_method(self):
# do something
class Inner(object):
def __init__(self):
self.Outer.some_method() # <-- this is the line in question
我该如何从Inner
类访问Outer
类的方法呢?
16 个回答
51
也许我有点疯狂,但这看起来确实很简单——关键是要在外部类的方法里面定义你的内部类...
def do_sthg(self):
...
def mess_around(self):
outer_class_self = self
class Mooble():
def do_sthg_different(self):
...
outer_class_self.do_sthg()
而且... “self”只是一个约定,所以你可以这样做:
def do_sthg(self):
...
def mess_around(outer_class_self):
class Mooble():
def do_sthg_different(self):
...
outer_class_self.do_sthg()
有人可能会反对说,这样你就不能在外部类之外创建这个内部类了... 但这并不是真的:
class Bumblebee():
def do_sthg(self):
print "sthg"
def give_me_an_inner_class(outer_class_self):
class Mooble():
def do_sthg_different(self):
print "something diff\n"
outer_class_self.do_sthg()
return Mooble
然后,在很远的地方:
blob = Bumblebee().give_me_an_inner_class()()
blob.do_sthg_different()
甚至可以大胆一点,扩展这个内部类(注意,要让 super()
正常工作,你需要把 Mooble
的类签名改成 class Mooble(object)
)。
class InnerBumblebeeWithAddedBounce(Bumblebee().give_me_an_inner_class()):
def bounce(self):
print "bounce"
def do_sthg_different(self):
super(InnerBumblebeeWithAddedBounce, self).do_sthg_different()
print "and more different"
ibwab = InnerBumblebeeWithAddedBounce()
ibwab.bounce()
ibwab.do_sthg_different()
稍后
mrh1997 提出了一个有趣的观点,关于使用这种技术创建的内部类的非传统继承。但看起来解决方案相当简单:
class Fatty():
def do_sthg(self):
pass
class InnerFatty(object):
pass
def give_me_an_inner_fatty_class(self):
class ExtendedInnerFatty(Fatty.InnerFatty):
pass
return ExtendedInnerFatty
fatty1 = Fatty()
fatty2 = Fatty()
innerFattyClass1 = fatty1.give_me_an_inner_fatty_class()
innerFattyClass2 = fatty2.give_me_an_inner_fatty_class()
print (issubclass(innerFattyClass1, Fatty.InnerFatty))
print (issubclass(innerFattyClass2, Fatty.InnerFatty))
143
你想从内部类的实例访问外部类的实例。解决这个问题的方法是使用工厂方法来创建内部类的实例,并把外部类的实例传递给它。
class Outer(object):
def createInner(self):
return Outer.Inner(self)
class Inner(object):
def __init__(self, outer_instance):
self.outer_instance = outer_instance
self.outer_instance.somemethod()
def inner_method(self):
self.outer_instance.anothermethod()
104
嵌套类的方法不能直接访问外部类的实例属性。
需要注意的是,即使你创建了一个内部类的实例,外部类的实例不一定存在。
实际上,很多时候不建议使用嵌套类,因为嵌套并不意味着内部类和外部类之间有特别的关系。