python中类内部的类的命名空间

2024-04-26 14:32:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图理解Python2.7中名称空间的嵌套。在

考虑以下不工作的代码:

class c(object):
  def debug(self):
     print globals(),locals()
     print x,y

class a(object):
   x=7 
   def __init__(self):
     self.y=9
   class b(object):
      def debug(self):
         print globals(),locals()
         print x,y
   class d(c):
      pass

如何从调用中访问变量x和y

^{pr2}$

他们似乎都看不到x或y

讨论后编辑,似乎只有显式地扩展嵌套类的信息才能达到我想要的(避免引用全局变量)。例如

class a(object):
   #
   @classmethod
   def _initClass(cls):
     for v in dir(cls):
       if type(cls.__dict__[v])==type:
         setattr(cls.__dict__[v],'vader',cls)   
   #
   x=7 
   class b(object):
     def debug(self):
       print b.vader.x
   class d(c):
     pass

 a._initClass()

即使这种技术对于访问实例变量似乎也没有什么用处,正如a().d().debug序列中所预期的那样。在


Tags: debugself名称objectdeftypepassdict
2条回答

马蒂金已经给了一个很好的答复,但我要自己动手。在

正如Martijn所说,在第一次导入类声明的模块时,类声明的执行方式与一次性函数类似,具有自己的局部作用域。在执行了类声明中的所有内容之后,这个局部作用域中剩余的内容都将用作类的字典。因此x__init__b、和{}都是a类对象的属性。您的类bd也是如此;它们的主体在导入模块时执行,剩余的本地作用域也用作它们的字典。在

代码不能工作的原因是,当debug方法执行时,它只知道全局作用域和它自己的局部作用域。在Python中,方法不隐式地将类实例的字典作为它们的范围的一部分,如它们在C++语言中所做的那样。类实例作为self参数显式可用,该参数出现在参数列表中(因此,Python控制台中Python的zen“explicit优于implicit”tryimport this)。在

另外,在访问和实例化b和{}上的其他类b和{}之前,是否实例化{}并不重要,因为b和{}都是{}上的类属性。因此,python可以成功地从a的实例或对a类对象的直接引用中检索{}和{}。在

class对象创建作用域;类主体只执行一次并丢弃,即生成类属性的本地命名空间。类主体从不参与嵌套作用域;在解析非本地名称时,它们将被完全忽略。在

因此,x = 7不是嵌套的b类(或其方法)可以访问的名称。相反,它是a上的类属性。访问a.x将起作用。y是一个实例属性,您必须有对实例的引用才能在其他任何地方访问它。在

注意,这同样适用于class b;它现在是a上的一个类属性,就像x是一个类属性一样。在

你的类b除了如何引用类对象之外,没有什么特别的地方。仅仅因为您创建了a的实例,并不意味着{}对它有任何特权访问;a().b()并不在实例之间创建关系。你可以:

b = a.b
b_instance = b()

不会有什么区别。你甚至可以:

^{pr2}$

世界不会崩溃!(真想不到)。在

相关问题 更多 >