Skip to content

Latest commit

 

History

History
274 lines (187 loc) · 4.61 KB

42.私有化.md

File metadata and controls

274 lines (187 loc) · 4.61 KB

私有化

一.下划线作用

1.公有变量

结构:

xx

作用:

定义变量

2.前置单下划线

结构:

_x

作用:

私有化属性或方法,from somemodule import *禁止导入,类对象和子类可以访问

3.前置双下划线

结构:

__xx

作用:

避免与子类中的属性命名冲突,无法在外部直接访问(名字重整所以访问不到)

4.前后双下划线

结构:

__xx__

作用:

用户名字空间的魔法对象或属性。例如:__init__ 不要自己发明这样的名字

5.单后置下划线

结构:

xx_

作用:

用于避免与Python关键词的冲突

6.下划线隔开

结构:

xx_xx_xx

作用:

用于命令时连接符

二.私有方法属性功能访问验证

demo:

如下新建文件demo01.py:

class Person(object):
    def __init__(self, name, age, taste):
        self.name = name
        self._age = age
        self.__taste = taste

    def showperson(self):
        print(self.name)
        print(self._age)
        print(self.__taste)

    def dowork(self):
        self._work()
        self.__away()

    def _work(self):
        print('my _work')

    def __away(self):
        print('my __away')


p = Person(name="lisi",age=18,taste="哈哈")
print(p.name)
print(p._age)
print(p.__taste) 

运行结果:

lisi
Traceback (most recent call last):
18
  File demo01_verify.py, line 26, in <module>
    print(p.__taste)
AttributeError: 'Person' object has no attribute '__taste'

这个时候我们发现_属性名是可以访问的,而__属性名是不可以访问的

三.from导入问题验证

demo:

如下在新建文件demo01.py添加一个全局变量_arges = "123":

_arges = "哈哈"  # 创建这一行
class Person(object):
    def __init__(self, name, age, taste):
        self.name = name
        self._age = age
        self.__taste = taste

    def showperson(self):
        print(self.name)
        print(self._age)
        print(self.__taste)

    def dowork(self):
        self._work()
        self.__away()

    def _work(self):
        print('my _work')

    def __away(self):
        print('my __away')


p = Person(name="lisi",age=18,taste="哈哈")
print(p.name)
print(p._age)
# print(p.__taste)

再创建一个文件demo02来导入demo01中的全局变量

import demo01
print(demo01._arges)

运行结果:

哈哈

如果我们用from xxx import xxx来用呢?

from demo01 import *
print(_arges)

运行结果:

Traceback (most recent call last):
  File webServer1.1.py, line 4, in <module>
    print(_arges)
NameError: name '_arges' is not defined

四.私有化属性访问

python没有绝对的私有化即使是__属性名的这种也可以通过一些方法来访问

注意:

不建议使用,建议调试使用

结构:

对象._类名__属性名

demo:

class Person(object):
    def __init__(self, name, age, taste):
        self.name = name
        self._age = age
        self.__taste = taste

    def showperson(self):
        print(self.name)
        print(self._age)
        print(self.__taste)

    def dowork(self):
        self._work()
        self.__away()

    def _work(self):
        print('my _work')

    def __away(self):
        print('my __away')


p = Person(name="lisi", age=18, taste="哈哈")
print(p.name)
print(p._age)
# 下面的方法不能访问
# print(p.__taste)
# 按照下面的方法可以访问
print(p._Person__taste)

运行结果:

lisi
18
哈哈

小总结:

在__init__方法中添加的__私有属性名私有变量会经过名字的重整_Class__object

通过name mangling(名字重整(目的就是以防子类意外重写基类的方法或者属性)如:_Class__object)机制就可以访问private了。

五.总结

  • 父类中属性名为__名字的,子类不继承,子类不能访问
  • 如果在子类中向__名字这样的属性赋值,通常会创建一个与父类相同名字的属性,但它实际上是在子类中创建的一个新属性,而不是覆盖父类的属性。
  • _名的变量、函数、类在使用from xxx import *时都不会被导入
class Parent:
    def __init__(self):
        self.__name = "Parent's name"

class Child(Parent):
    def __init__(self):
        super().__init__()
        self.__name = "Child's name"

parent = Parent()
child = Child()

print(parent._Parent__name)  # 输出 "Parent's name"
print(child._Child__name)  # 输出 "Child's name"