首先,我要说的是,我已经对这方面进行了广泛的研究,但是没有运气。我查看了许多示例和类似情况,例如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
答案 0 :(得分:4)
创建新类时,将执行主体中的代码,并将生成的名称传递到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
答案 1 :(得分:1)
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
答案 2 :(得分:0)
如果您有理由不使用MainClass.InnerSubClass
,则还可以在type(self)
内使用self.__class__
或__init__
(OK, but which one)来获取包含的类。这可以在很多层上很好地工作(无论如何都不应该发生),并且要求传递给super
的参数是实例的类型(无论如何应该是),但是如果您子类化< / strong>,如here所示。比起范围规则,这个概念对您而言可能更清晰:
class MainClass:
class Inner:
pass
class InnerSub(Inner):
def __init__(self):
print(super(self.__class__))
print(super(type(self)))
MainClass().InnerSub()