当前位置: 首页 > 面试题库 >

为什么Python的“私有”方法实际上不是私有的?

戚弘和
2023-03-14
问题内容

Python使我们能够在类中创建“私有”方法和变量,方法是在名称前加上双下划线,例如:__myPrivateMethod()。那么,如何解释这一点

>>> class MyClass:
...     def myPublicMethod(self):
...             print 'public method'
...     def __myPrivateMethod(self):
...             print 'this is private!!'
... 
>>> obj = MyClass()
>>> obj.myPublicMethod()
public method
>>> obj.__myPrivateMethod()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: MyClass instance has no attribute '__myPrivateMethod'
>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']
>>> obj._MyClass__myPrivateMethod()
this is private!!

这是怎么回事?!

我会为那些不太了解的人解释一下。

>>> class MyClass:
...     def myPublicMethod(self):
...             print 'public method'
...     def __myPrivateMethod(self):
...             print 'this is private!!'
... 
>>> obj = MyClass()

我在那里所做的是创建一个具有公共方法和私有方法的类,并将其实例化。

接下来,我将其称为public方法。

>>> obj.myPublicMethod()
public method

接下来,我尝试调用其私有方法。

>>> obj.__myPrivateMethod()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: MyClass instance has no attribute '__myPrivateMethod'

这里看起来一切都很好。我们无法调用它。实际上,它是“私有”的。好吧,实际上不是。在对象上运行dir()揭示了python为所有“私有”方法神奇地创建的新的神奇方法。

>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']

此新方法的名称始终是下划线,其后是类名,然后是方法名。

>>> obj._MyClass__myPrivateMethod()
this is private!!

封装这么多,是吗?

无论如何,我总是会听到Python不支持封装,那么为什么还要尝试呢?是什么赋予了?


问题答案:

名称加扰用于确保子类不会意外覆盖其超类的私有方法和属性。它并非旨在防止从外部故意访问。

例如:

>>> class Foo(object):
...     def __init__(self):
...         self.__baz = 42
...     def foo(self):
...         print self.__baz
...     
>>> class Bar(Foo):
...     def __init__(self):
...         super(Bar, self).__init__()
...         self.__baz = 21
...     def bar(self):
...         print self.__baz
...
>>> x = Bar()
>>> x.foo()
42
>>> x.bar()
21
>>> print x.__dict__
{'_Bar__baz': 21, '_Foo__baz': 42}

当然,如果两个不同的类具有相同的名称,它就会崩溃。



 类似资料:
  • 问题内容: 在阅读有关同步的内容时,我遇到了“监视器模式”以封装可变状态。 以下是示例代码 } 用私有锁代替固有锁更好吗? 问题答案: 是的-这意味着您可以看到 所有可能获得该锁的代码 (不考虑反射的可能性)。 如果您锁定(这是我假设您通过“固有锁定”所指的),那么其他代码可以做到: 该代码可能与自己的代码相距很远,并且可能调用其他方法,这些方法又将监视器带走。在这里很容易陷入死锁领域,因为您不容

  • 在 Python 的面向对象编程中,私有属性是只能在类的实例方法中访问的属性,不允许在外界访问私有属性。 1. 私有属性的定义 1.1 定义 在属性名称前加上前缀 __,表示该属性为私有属性,示例代码如下: class Object: def method(self): self.__private_attribute = 123 在第 3 行,创建一个私有属性 __pr

  • 问题内容: 我在内部类中有一个私有方法,我想使用SafeVarargs批注。但是,我需要使用静态方法或最终方法。为什么私有方法也需要最终确定?这不是多余的吗? 问题答案: 这是多余的,并且您提出了一个很好的观点。 我认为要求final或static的真正原因是强制不能重写该方法,因此子类不能以使@SafeVarargs注释对方法的定义无效的方式篡改数据。 但是,尽管这是多余的,但它并不是一个糟糕的

  • 问题内容: 我不应该能够调用实例化对象的私有方法。我想知道为什么下面的代码有效。 我知道可以从类中访问私有方法。但是,如果类中的方法实例化了同一类的对象,则作用域规则是否不适用于该实例化的对象? 如本例所示,像main这样的静态方法可以访问类的非静态成员吗​​? 问题答案: 您的方法是的方法,因此可以调用的私有方法。 只是因为它是一个方法并不妨碍它表现得像为目的的方法,等等。 只是阻止的方法 等

  • 本文向大家介绍程序计数器为什么是私有的?相关面试题,主要包含被问及程序计数器为什么是私有的?时的应答技巧和注意事项,需要的朋友参考一下 程序计数器主要有下面两个作用: 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。 需要注意

  • 问题内容: 我是Java的新手,并且正在学习封装,并看到了一个示例,其中实例变量在类中声明为私有。 http://www.tutorialspoint.com/java/java_encapsulation.htm 我有2个查询: 为什么实例变量是私有的?为什么不公开? 如果实例变量被公开并直接访问怎么办?我们看到约束了吗? 您能用一个例子说明在Java类中将实例变量声明为public时会出现什么