T. *_*one 86 python scope nested inner-classes
我有这样的情况......
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
Run Code Online (Sandbox Code Playgroud)
如何Outer从Inner类中访问类的方法?
编辑 - 感谢您的回复.我的结论是,我需要重新评估我是如何设计这个实现的,并提出一个更强大的方法.
Dan*_*llo 57
嵌套类的方法不能直接访问外部类的实例的属性.
请注意,这并不一定,甚至当你创建内部类的实例存在的外部类的一个实例的情况.
实际上,通常建议不要使用嵌套类,因为嵌套并不意味着内部类和外部类之间存在任何特定关系.
小智 50
您正在尝试从内部类实例访问Outer的类实例.所以只需使用factory-method构建Inner实例并将Outer实例传递给它.
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()
Run Code Online (Sandbox Code Playgroud)
mik*_*ent 24
也许我很生气,但这似乎很容易 - 事情是让你的内部类在外部类的方法中...
def do_sthg( self ):
...
def messAround( self ):
outerClassSelf = self
class mooble():
def do_sthg_different( self ):
...
outerClassSelf.do_sthg()
Run Code Online (Sandbox Code Playgroud)
另外......"self"仅按惯例使用,因此您可以这样做:
def do_sthg( self ):
...
def messAround( outerClassSelf ):
class mooble():
def do_sthg_different( self ):
...
outerClassSelf.do_sthg()
Run Code Online (Sandbox Code Playgroud)
可能有人反对说,你不能从外部类外部创建这个内部类......但事实并非如此:
class Bumblebee():
def do_sthg( self ):
print "sthg"
def giveMeAnInnerClass( outerClassSelf ):
class mooble():
def do_sthg_different( self ):
print "something diff\n"
outerClassSelf.do_sthg()
return mooble
Run Code Online (Sandbox Code Playgroud)
然后,在几英里之外:
blob = Bumblebee().giveMeAnInnerClass()()
blob.do_sthg_different()
Run Code Online (Sandbox Code Playgroud)
甚至将船推出一点并扩展这个内部类(NB以获得super()工作你必须将mooble的类签名改为"class mooble(object)"
class InnerBumblebeeWithAddedBounce( Bumblebee().giveMeAnInnerClass() ):
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()
Run Code Online (Sandbox Code Playgroud)
后来
mrh1997提出了一个关于使用这种技术传递的内部类的非公共继承的有趣观点.但似乎解决方案非常简单:
class Fatty():
def do_sthg( self ):
pass
class InnerFatty( object ):
pass
def giveMeAnInnerFattyClass(self):
class ExtendedInnerFatty( Fatty.InnerFatty ):
pass
return ExtendedInnerFatty
fatty1 = Fatty()
fatty2 = Fatty()
innerFattyClass1 = fatty1.giveMeAnInnerFattyClass()
innerFattyClass2 = fatty2.giveMeAnInnerFattyClass()
print ( issubclass( innerFattyClass1, Fatty.InnerFatty ))
print ( issubclass( innerFattyClass2, Fatty.InnerFatty ))
Run Code Online (Sandbox Code Playgroud)
esp*_*sp0 10
晚了几年......但是为了扩展@mike rodent的精彩答案,我在下面提供了我自己的示例,展示了他的解决方案是多么灵活,以及为什么它应该(或应该)被接受回答。
Python 3.7
class Parent():
def __init__(self, name):
self.name = name
self.children = []
class Inner(object):
pass
def Child(self, name):
parent = self
class Child(Parent.Inner):
def __init__(self, name):
self.name = name
self.parent = parent
parent.children.append(self)
return Child(name)
parent = Parent('Bar')
child1 = parent.Child('Foo')
child2 = parent.Child('World')
print(
# Getting its first childs name
child1.name, # From itself
parent.children[0].name, # From its parent
# Also works with the second child
child2.name,
parent.children[1].name,
# Go nuts if you want
child2.parent.children[0].name,
child1.parent.children[1].name
)
print(
# Getting the parents name
parent.name, # From itself
child1.parent.name, # From its children
child2.parent.name,
# Go nuts again if you want
parent.children[0].parent.name,
parent.children[1].parent.name,
# Or insane
child2.parent.children[0].parent.children[1].parent.name,
child1.parent.children[1].parent.children[0].parent.name
)
# Second parent? No problem
parent2 = Parent('John')
child3 = parent2.Child('Doe')
child4 = parent2.Child('Appleseed')
print(
child3.name, parent2.children[0].name,
child4.name, parent2.children[1].name,
parent2.name # ....
)
Run Code Online (Sandbox Code Playgroud)
输出:
Foo Foo World World Foo World
Bar Bar Bar Bar Bar Bar Bar
Doe Doe Appleseed Appleseed John
Run Code Online (Sandbox Code Playgroud)
再次,一个精彩的答案,支持你,迈克!
我找到了这个。
调整以适应您的问题:
class Outer(object):
def some_method(self):
# do something
class _Inner(object):
def __init__(self, outer):
outer.some_method()
def Inner(self):
return _Inner(self)
Run Code Online (Sandbox Code Playgroud)
我相信你可以以某种方式为这个或其他东西写一个装饰器
| 归档时间: |
|
| 查看次数: |
63994 次 |
| 最近记录: |