Access control for Python learning

Python is an object-oriented language from the beginning of its design, and the first element of object-oriented thinking is encapsulation. The so-called encapsulation, generally speaking, is the attributes and methods in the class, which are divided into public and private. The public can be accessed by the outside world, and the private cannot be accessed by the outside world. This is the most critical concept in encapsulation - access control. What this article shares with you is access control related content, let's take a look, I hope it will be helpful to children's shoes who want to learn python .

  There are three levels of access control: private, protected, public

  Private ( Private ): Only the class itself can access Protected ( Protected ): Only the class itself and subclasses can access Public ( Public ): Any class can access

  Since Python is not like Java , it has access control characters ( private / public / protected ), so Python 's access control is also easy to be ignored and mistaken by candidates.

  Public ( Public )

  In Python classes, attributes defined by default are public.

  classFoo(object): 

  bar = 123

  def__init__(self, bob): 

  self.bob = bob

  print(Foo.bar)  # 123

  foo = Foo(456)

  print(foo.bob)  # 456

 The bar attribute in the   above class Foo is a class attribute, the bob defined in the __init__ method is an instance attribute,  bar and bob are public attributes that can be accessed externally, print the bar in the class  and the bob in the instance respectively , and output the corresponding value.          

  Protected _ _

To define a protected attribute    in Python , just add an underscore _ before its name . We change the bob and bar in the Foo method to _bob and _bar , and they become protected attributes. The code is as follows:        

  classFoo(object): 

  _bar = 123

  def__init__(self, bob): 

  self._bob = bob

  class Son(Foo):

  def print_bob(self):

  print(self._bob)

  @classmethod

  def print_bar(cls):

  print(cls._bar)

  Son.print_bar()  # 123

  son = Son(456)

  son.print_bob()  # 456

  定义一个类 Son 继承自 Foo ,由于受保护的对象只能在类的内部和子类中被访问,不能直接调用 print(Son._bar)  print(son._bob) 来输出这两个属性的值,所以定义了 print_bar print_bob 方法,实现在子类中输出,这段代码也正常的输出了 _bar  _bob 的值。

  接下来,试着反向验证一下,在类的外部,能不能访问其属性,将上面代码的输出部分修改如下:

  print(Son._bar)  # 123

  son = Son(456)

  print(son._bob)  # 456

  (假装)惊讶的发现,竟然没有报错,也输出了正确的值。

  Python中用加下划线来定义受保护变量,是一种约定的规范,而不是语言层面真的实现了访问控制,所以,我们定义的保护变量,依然可以在外部被访问到(这是个feature,不是bug)。

  私有(private

  Python定义私有属性,需要在属性名前加两个下划线 __ ,把上面的代码修改一下,运行一下会发现下面的代码中的任何一个print都会报错的。

  class Foo(object):

  __bar = 123

  def __init__(self, bob):

  self.__bob = bob

  class Son(Foo):

  def print_bob(self):

  print(self.__bob)  # Error

  @classmethod

  def print_bar(cls):

  print(cls.__bar)  # Error

  print(Son.__bar)  # Error

  son = Son(456)

  print(son._bob)  # Error

  深入一下——私有属性真的就访问不到了吗?

  要了解私有属性是否真的访问不到,需要从Python是如何实现私有属性入手。CPython中,会把双下划线的属性变为 _ClassName__PropertyName 的形式,用代码演示一下:

  class Foo(object):

  __bar = 123

  print(Foo._Foo__bar)  # 123

  运行一下可以知道,正常输出了 __bar 的值,但是不推荐这样去访问私有属性,因为不同的Python解释器对于私有属性的处理不一样。

  特例

  使用双下划线定义私有属性,有一种特殊情况,当属性后也有两个下划线的时候,这个属性会被Python解释器当做魔术方法,从而不做私有处理。

  class Foo(object):

  __bar__ = 123

  print(Foo.__bar__)  # 123

  上面代码输出了123,证明Python解释器并没有把 __bar__ 当做私有属性。当定义私有属性时,需要注意名字最后最多只能有一个下划线。

  另一个特例

  假如定义的属性名就叫 __ 呢?不妨直接试一下:

  class Foo(object):

  __ = 123

  print(Foo.__)  # 123

  可以发现名字叫 __ 的属性也不会被认为是私有属性,名字是多个下划线的属性也不是私有属性(比如 _______ )。

 

 

来源:网络

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324818592&siteId=291194637