Python 类中的变量范围
Posted
技术标签:
【中文标题】Python 类中的变量范围【英文标题】:Variable scopes in Python classes 【发布时间】:2022-01-11 08:25:20 【问题描述】:在类中(函数外)声明变量:所有类函数都可以访问它(基本上是公共变量)
在类中的函数内声明变量:只有该函数可以访问它(它在该函数的范围内)
在类内的函数内用self.(variable name)
声明变量:所有类函数都可以访问它(这与global (variable name)
有何不同?)
而且由于没有私有/受保护,所有内容都是公共的,因此从类内部访问的所有内容都可以从类外部访问。
还有其他我应该知道的细微差别,或者我已经知道了吗?
【问题讨论】:
但是基本上,是的,ypu 在 Python 中默认没有“私有”变量之类的东西(我说“默认”是因为人们可以使用一些自省魔法来获得类似私有/受保护的行为) .现在,为什么需要私有变量?约定是名称以单个“_”开头的方法/属性不是公共的,不应从对象外部修改。用于混淆/安全的私有变量的想法本质上是错误的。 【参考方案1】:由于您问题中的列表不是 100% 清楚,我决定用一个简单的例子来解释它。它还包括一些您未在列表中提及的变量,例如 __something
变量。
class Test:
a = None
b = None
def __init__(self, a):
print self.a
self.a = a
self._x = 123
self.__y = 123
b = 'meow'
一开始,a
和 b
只是为类本身定义的变量 - 可通过 Test.a
和 Test.b
访问,并不特定于任何实例。
在创建该类的实例时(导致__init__
被执行):
print self.a
没有找到实例变量,因此返回了类变量
self.a = a
:创建了一个新的实例变量a
。这会隐藏类变量,因此self.a
现在将引用实例变量;要访问类变量,您现在必须使用 Test.a
对self._x
的赋值会创建一个新的实例变量。它被认为是“不是公共 API 的一部分”(又名受保护),但从技术上讲,它没有不同的行为。
对self.__y
的赋值会创建一个名为_Test__y
的新实例变量,也就是说,它的名称是错位的,因此除非您使用错位名称,否则它不能从类外部访问。这可用于“私有”变量。
对b
的赋值会创建一个局部变量。除了 __init__
函数之外,它在任何地方都无法使用,因为它没有保存在实例、类或全局范围内。
【讨论】:
您不使用Test(object)
有什么原因吗?那么你的答案是否也适用于new-type 类?
@DavorJosipovic 有个东西叫 Python3。
如果我们像这样调用类:** obj = Test("name") ** 那么这个 obj 是实例或对象。这个 obj 到底是什么。
另外,__init__(self, a)
中的参数a
仅是__init__
中的局部变量。【参考方案2】:
在类的顶层声明一个变量就像声明一个静态或类变量。用 self 限定它是声明一个实例变量。可以通过类名(例如Class.x = 5
)引用它们来修改类变量,并且所有实例都将继承这些更改。实例变量是实例私有的,只能由该实例修改。
您可以使用下划线实现某种程度的访问控制。见private variables in the Python tutorial。按照惯例,变量以一个下划线开头,例如_foo
是 API 的非公开部分,名称以两个下划线开头,例如__foo
的名称 mangled 将变为 _classname__foo
。
【讨论】:
【参考方案3】:虽然已回答,但让我为您的问题添加一些 cmets:
在类中声明一个变量(在函数之外):所有类函数都可以访问它(基本上是一个公共变量): 注释:这就像一个静态变量,可以使用类名来调用。这些变量对所有函数都可用,任何函数都可以修改并打印出来。
在类内的函数内声明变量:只有该函数可以访问它(在该函数范围内): 注释:如果变量声明时没有 self ,那么它只能在该函数中访问,有点像局部变量。但是,如果它声明使用 self like self.var= 'somevalue', 那么它可以通过任何对象访问,但不能通过类名访问。
在类中的函数内用 self.(variable name) 声明一个变量:所有类函数都可以访问它(这与全局(变量名)有何不同?): 评论:见上部分的答案。
并且由于没有私有/受保护,所有内容都是公共的,因此可以从类内部访问的所有内容都可以从类外部访问。: 评论:是的,但是我们可以使用单个下划线来告诉世界这个变量是私有的,但从技术上讲实际上并没有使它成为私有。
【讨论】:
【参考方案4】:我们可以将 this 的作用域用于 as : 案例 1:在课堂上
class test:
def __init__(self, a):
self.__elements = a
def change_a(self): self.__elements = 5
案例2:课外
t = test(5)
这将作为 object._classname__privatevaribalename 访问
print(t._test__elements)
这将打印 a 的变化值
【讨论】:
以上是关于Python 类中的变量范围的主要内容,如果未能解决你的问题,请参考以下文章