Rya*_*yan 3 python scope namespaces python-3.x
对于Python 3.7
我有一个带有类属性(类范围变量)的类:
class foo:
var="value goes here"
Run Code Online (Sandbox Code Playgroud)
以及在类的init方法中创建的实例变量:
def __init__(self, var=var):
self.var=var
Run Code Online (Sandbox Code Playgroud)
类变量与init的参数具有相同的名称,这不会使解释器感到困惑,因为解释器将“=”符号左侧的任何字段视为该方法范围内的新变量。它通过为方法的范围填充一个新的命名空间(变量字典)来实现这一点,以数组的形式实现: 例如parameters[1] = "var"或关联数组:parameters['var'] = pointer_to_value。然后,解释器查看方法体内部,并用通用引用替换“=”符号右侧出现的对“var”的任何引用。事实上,这是一个谎言,但它比它真正的作用更容易理解:
解释器识别匹配的正则表达式
.*= *var(,{0,1}| *) *(;{0,1}|\n*),然后将相应的pointer_to_value传递到程序的调用堆栈)。因此,解释器并不关心参数的名称,也不会注意到 var=var 的歧义。可以解决歧义这一事实是语言结构的副作用,而不是有意的设计决策。毕竟,问问自己,在定义方法时,为什么要从定义的方法内部访问变量?为什么要从方法定义中调用对父作用域中的变量的赋值操作?这些都是不合逻辑的行为,并且它们的名称空间可能性是互斥的,因此解释器永远不需要解决歧义。
相反,解释器将“=”符号的右侧视为现有值,并在类的命名空间中搜索变量定义。
在方法中,实例变量也与类变量和参数具有相同的名称,这在init方法中起作用,因为实例变量是通过self引用访问的,例如
self.varname = varname
Run Code Online (Sandbox Code Playgroud)
我需要从另一个方法的方法定义中访问实例变量,并且我想对此函数的参数使用相同的名称:
def lookup(self, var=var):
print(var)
Run Code Online (Sandbox Code Playgroud)
表达式将var = var获取类属性还是实例属性?methodname(self)到底与自我有什么关系?是self对实际对象的引用,还是仅将解释器的行为从静态方法更改为实例方法?解释器是否会自动将“=”符号的右侧上下文化为键入的任何对象的实例属性methodname(object)?
在方法体内,如果我分配给var...
def lookup(self, var=var):
var = var
Run Code Online (Sandbox Code Playgroud)
我已经阅读了文档和一些 OOP 教程以及最近的一本书,但我仍然不清楚。
访问实例变量的唯一方法是作为self。
当你只是参考var,那永远不是实例变量;它始终是本地变量、封闭变量、全局变量或内置变量。
在您的方法定义中:
\n\ndef lookup(self, var=var):\n print(var)\nRun Code Online (Sandbox Code Playgroud)\n\n\xe2\x80\xa6 你有一个名为 的参数var。参数是局部变量。这print(var)打印该局部变量。
那这个呢?
\n\ndef lookup(self, var=var):\n var = var\nRun Code Online (Sandbox Code Playgroud)\n\n再次,var是一个局部变量\xe2\x80\x94a参数。因此,您只需将该局部变量的当前值分配给同一个变量。这没有任何有用的效果,但当然它是完全合法的。
参数的值从哪里来?在函数调用时,如果传递参数,则该参数将绑定到形参;如果不这样做,它将用默认值填充。
\n\n好的,那么默认值从哪里来呢?
\n\n在函数定义时(def执行语句时),var在当前作用域\xe2\x80\x94中查找,即定义的主体class\xe2\x80\x94,并将其值作为默认值存储在函数对象中(它应该显示为foo.lookup.__defaults__[0])。
因此,默认值为"value goes here"。
请注意,它不是闭包捕获或对类属性的其他引用。class执行该语句时,它使用相同的class主体命名空间来构建类的属性,因此最终会得到foo.var与 中相同值的另一个名称foo.lookup.__defaults__[0]。但它们是该值完全独立的名称;您可以重新分配foo.var = 3,并且 \'s 参数的默认值lookup仍然是"value goes here"。
因此,回答您的具体问题:
\n\n\n\n\n它将存储在类变量、实例变量还是同名的新变量中?
\n
以上都不是。它将它存储在一个已经存在的局部变量中,因为它是一个参数。
\n\n\n\n\n它会获取类变量、实例变量还是方法的变量?
\n
如果“方法的变量”指的是参数,那么它就是最后一个。
\n\n\n\n\n如何显式引用这些变量?
\n
与显式引用其他任何内容的方式相同:
\n\nvar是一个局部封闭全局或内置变量。self.var是实例属性,如果没有实例属性,则为类属性。type(self).var是一个类属性,即使有一个实例属性。| 归档时间: |
|
| 查看次数: |
531 次 |
| 最近记录: |