我能够在不使用 setter 方法的情况下将私有变量设置为另一个值。这怎么可能?它正在创建新参数吗?
I was able to set private variable to another value without using setter method. How is this possible? Is it creating new parameter?
谁能解释为什么我不用 setter 方法就可以设置私有变量?
是的,你可以。
Python 并没有真正的私有成员。然而,它做了一些棘手的命名事情来尝试完成。
如果您确实有一个 __member
名称,要在外部访问它,您可以使用 _<ClassName>__<member_name>
示例:
[ttucker@zim Whosebug]$ cat private.py
class MyClass:
def __init__(self):
self.__private = "initial"
def show(self):
print(self.__private)
private = MyClass()
private.show() # -> "initial"
# Does not actually set the private member,
# but creates a public member with the same name
private.__private = "new"
private.show() # -> "initial"
print(private.__private) # -> "new"
# This actually changes the "private" member.
private._MyClass__private = "new"
private.show() # -> "new"
执行:
[ttucker@zim Whosebug]$ python private.py
initial
initial
new
new
感谢@Tomerikoo 的回答。我想补充一点。
关键是 python 并没有真正的私有属性。基本上,python 仅更改私有属性的名称,格式如下:
_className__privateAttributeName
所以对于问题中的代码,属性 company
只是另一个新属性。为了验证这一点,我们可以使用dir(obj2)
查看详细信息。
>>> dir(obj2)
(Pdb) dir(obj2)
['_Employee__company', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__
', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__n
e__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook_
_', '__weakref__', 'company', 'get_company', 'name', 'set_company']
(Pdb)
正如我们所见,company
和 _Employee__company
只是两个不同的属性。
谁能解释为什么我不用 setter 方法就可以设置私有变量?
是的,你可以。
Python 并没有真正的私有成员。然而,它做了一些棘手的命名事情来尝试完成。
如果您确实有一个 __member
名称,要在外部访问它,您可以使用 _<ClassName>__<member_name>
示例:
[ttucker@zim Whosebug]$ cat private.py
class MyClass:
def __init__(self):
self.__private = "initial"
def show(self):
print(self.__private)
private = MyClass()
private.show() # -> "initial"
# Does not actually set the private member,
# but creates a public member with the same name
private.__private = "new"
private.show() # -> "initial"
print(private.__private) # -> "new"
# This actually changes the "private" member.
private._MyClass__private = "new"
private.show() # -> "new"
执行:
[ttucker@zim Whosebug]$ python private.py
initial
initial
new
new
感谢@Tomerikoo 的回答。我想补充一点。
关键是 python 并没有真正的私有属性。基本上,python 仅更改私有属性的名称,格式如下:
_className__privateAttributeName
所以对于问题中的代码,属性 company
只是另一个新属性。为了验证这一点,我们可以使用dir(obj2)
查看详细信息。
>>> dir(obj2)
(Pdb) dir(obj2)
['_Employee__company', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__
', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__n
e__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook_
_', '__weakref__', 'company', 'get_company', 'name', 'set_company']
(Pdb)
正如我们所见,company
和 _Employee__company
只是两个不同的属性。