Python v2嵌套子类“全局名称” ' 没有定义”
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python v2嵌套子类“全局名称” ' 没有定义”相关的知识,希望对你有一定的参考价值。
首先,让我说是的,我已经研究了几天,现在没有运气。我看过很多例子和类似的情况,比如this one,但到目前为止还没有什么能够解决我的问题。
我的问题是我有一个Python项目有一个主类,有两个嵌套类(是的,我知道),其中一个类是第一个的子类。我无法弄清楚为什么我一直得到NameError: global name 'InnerSubClass' is not defined
。
我理解作用域(这两个类都在相同的范围内)但我尝试的任何东西似乎都解决了这个问题(我希望将这两个类保持在最低限度),尽管这个问题适用于其他人。
这是我想要做的一个简单的例子:
class SomeClass(object):
def __init__(self):
"""lots of other working stuff"""
class MainClass(object):
def __init__(self):
self.stuff = []
self.moreStuffs = []
class InnerClass(object):
def __init__(self, thing, otherThing):
self.thing = thing
self.otherThing = otherThing
self.otherStuff = []
class InnerSubClass(InnerClass):
def __init__(self, thing, otherThing, newThing):
super(InnerSubClass).__init__(thing, otherThing)
self.newThing = newThing
"""other code that worked before the addition of 'InnerSubClass'"""
def doSomething(self):
innerclass = self.InnerSubClass('thisthing', 'thatthing', 'thingthing')
print("just more thing words %s" % innerclass.newThing)
myThing = MainClass()
myThing.doSomething()
我试过改变super(InnerSubClass).__init__(thing, otherThing)
到super(InnerClass.InnerSubClass).__init__(thing, otherThing)
甚至super(MainClass.InnerClass.InnerSubClass).__init__(thing, otherThing)
没有成功。我让“InnerSubClass”直接从对象InnerSubClass(object):
等继承,但它仍然不起作用。
虽然我不是一个经验丰富的python开发人员,而是来自大多数其他编译的OO语言,但似乎无法解决为什么这不起作用。如果我摆脱“InnerSubClass”,一切都很好。
看起来python不像其他语言那样提供“私有”类和函数,这很好,但我想利用嵌套来至少保持对象“集中”在一起。在这种情况下,除了“MainClass”中的函数之外,什么都不应该实例化“InnerClass”或“InnerSubClass”。
请提供有用的建议,并解释为什么它不能按预期工作,并提供有关如何正确完成此操作的背景信息。如果这看起来很简单,那么它现在已经被弄清楚了。
编辑:为了澄清,这仅适用于v2
There is no "class scope" in lookup order
创建新类时,将执行正文中的代码,并将生成的名称传递给type
进行创建。 Python查找从内部到外部,但您没有“类级别”,只有您定义的名称才能成为新类的属性/方法。实际上,如果要访问方法中的类变量,可以使用MyClass.attr
而不是简单的attr
。
继承是有效的,因为InnerSubClass(InnerClass)
发生在类创建中。要在创建InnerClass
之后访问MainClass
,请执行与类属性相同的操作:MainClass.InnerClass
仅举一个例子:
class Outer:
out = 1
class Inner:
inside = 2
try:
print(out) # this is confusing
except NameError:
print("can't find out")
def f(self):
try:
print(inside) # this is clear
except NameError:
print("can't find inside")
try:
print(Inner.inside) # this is less clear
except NameError:
print("can't find Inner.inside")
Outer.Inner().f()
# can't find anything
编辑:
以上是一般视图,直接应用于您的情况,以您查看常规类属性的方式查看内部类。你可以访问这些MyClass.attr
,其中MyClass
是全球定义的。如果用attr
替换InnerSubClass
,你就得到了类(属性查找不关心继承,而是关于属性的位置)。
一个带有嵌套继承类的精简示例:
class MainClass(object):
class Inner(object):
pass
class InnerSub(Inner):
def __init__(self):
print(super(MainClass.InnerSub)) # note you use MainClass, known globally
def f(self):
return self.InnerSub()
MainClass().f() # prints "<super ...>" and returns a MainCLass.InnerSub object
Here他们这样做
super(MainClass.InnerSubClass, self).__init__(thing, otherThing)
所以你可以在这里测试它是完整的工作示例
class SomeClass(object):
def __init__(self):
"""lots of other working stuff"""
class MainClass(object):
def __init__(self):
self.stuff = []
self.moreStuffs = []
class InnerClass(object):
def __init__(self, thing, otherThing):
self.thing = thing
self.otherThing = otherThing
self.otherStuff = []
class InnerSubClass(InnerClass):
def __init__(self, thing, otherThing, newThing):
super(MainClass.InnerSubClass, self).__init__(thing, otherThing)
self.newThing = newThing
"""other code that worked before the addition of 'InnerSubClass'"""
def doSomething(self):
innerclass = self.InnerSubClass('thisthing', 'thatthing', 'thingthing')
print("just more thing words %s" % innerclass.newThing)
print("and I also inherit from InnerClass %s" % innerclass.otherThing)
myThing = MainClass()
myThing.doSomething()
输出是
just more thing words thingthing
and I also inherit from InnerClass thatthing
如果你有理由不使用MainClass.InnerSubClass
,你也可以在type(self)
中使用self.__class__
或OK, but which one(__init__
)来获得包含类。这很好地适用于很多层(无论如何都不应该发生),并且要求传递给super
的参数是实例的类型(它应该是它应该是)但是如果你是子类,则会中断,如here所示。这个概念可能比范围规则更清晰:
class MainClass:
class Inner:
pass
class InnerSub(Inner):
def __init__(self):
print(super(self.__class__))
print(super(type(self)))
MainClass().InnerSub()
以上是关于Python v2嵌套子类“全局名称” ' 没有定义”的主要内容,如果未能解决你的问题,请参考以下文章