再谈python的方法和属性私有化:单下划线,双下划线

1.python的私有化:_

  1. xx: 公有变量
  2. _x: 单前置下划线,私有化属性或方法,禁止通过from modules import *导入,但是类对象和子类可以访问
  3. __xx:双前置下划线,避免与子类中的属性命名冲突,无法在外部直接访问(名字重整所以访问不到),类对象和子类不能访问
  4. __xx__:双前后下划线,用户名字空间的魔法对象或属性。例如:__init__ , __ 尽量不要自定义这种形式的。
  5. xx_:单后置下划线,用于避免与Python关键词的冲突

2.单个_下划线和__两个下划线的区别

class Person(object):
    def __init__(self, name, age, speak):
        self.name = name
        self._age = age  #使用一个下划线来私有属性'_'
        self.__speak = speak #使用两个下划线来私有属性‘_’

    def showperson(self):
        print(self.name,self._age,self.__speak)

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

    def _work(self):  #注意,这是一个下划线修饰的私有方法
        print('my _work')

    def __away(self): #注意,这是两个下划线私有的属性
        print('my __away')

class Student(Person):  #Student继承父类Person
    def construction(self, name, age, speak): #该防范功能是给属性重新赋值。
        self.name = name
        self._age = age
        self.__speak = speak

    def showstudent(self):
        print(self.name,self._age,self.__speak)

    @staticmethod  #静态方法,不需要定义参数
    def testbug():
        _Bug.showbug() #可以调用了外部的单下划线修饰的模块的方法。

#单个下划线修饰的“_”的变量、函数、类在使用from xxx import *时都不会被导入
class _Bug(object):  #单个下划线修饰的私有类。
    @staticmethod
    def showbug():
        print("showbug")

#------------------------------------------数据测试--------------------------------------

#1.子类可以调用父类中的公有方法,属性,包括父类的中用单个下划线_修饰的私有属性和方法
s1 = Student('jack', 25, 'Chinese')#创建Student的实例s1,因为s1没有__init__方法,调用父类的方法
s1.showperson()  #调用继承父类的showperson()方法
print(s1.name,s1._age)
s1.dowork()
s1._work()
#s1.__away  子类无法访问父类中用两个下划线修饰的私有方法。
#print(s1.__speak) 报错,两个__下划线修饰的属性方法子类无法直接访问。
'''
jack 25 Chinese
jack 25
my _work
my __away
my _work
'''

#2.子类不能访问父类中两个下划线__修饰的方法和属性,也不能修改父类中双下划线的属性。但是单下划线属性可以修改
#s1.showstudent() 报错,因为子类Student没有定义自己的属性,name,age,speak,都是继承父类的,方法中调用的私有属性不能访问
s1.construction('rose', 30, 'English') #子类对继承的属性重新赋值
s1.showperson()  #rose 30 Chinese  注意,调用父类的方法,__speak双下划线的属性没有被修改。
#如果在子类中向__名字赋值,那么会在子类中定义的一个与父类相同名字的属性

s1.showstudent()  #rose 30 English 这里调用子类的自己的方法,__speak被修改了。

Student.testbug()  #showbug

总结:

  • 父类中属性名为__名字的,子类不继承,子类不能访问
  • 如果在子类中向__名字赋值,那么会在子类中定义的一个与父类相同名字的属性
  • _名的变量、函数、类在使用from xxx import *时都不会被导入

3.为什么__可以私有化属性或方法哈?

class Person(object):
    def __init__(self,name,age):
        self.__name = name
        self.age = age

p1 = Person("Tom",19)
#print(p1.name),#报错,因为私有属性不能直接访问,那么为什么加了__就不可访问了呢?
print(p1.age)
print(p1.__dict__) #{'_Person__name': 'Tom', 'age': 19}

尖叫提示:其实__方式的私有属性不可访问的原理很简单,那就是将属性名字改了不就行了哈。使用__dict__显示一个实例所有属性,可以发现name被改成了_Person__name,所以你访问name报错啦。 

统一声明:关于原创博客内容,可能会有部分内容参考自互联网,如有原创链接会声明引用;如找不到原创链接,在此声明如有侵权请联系删除哈。关于转载博客,如有原创链接会声明;如找不到原创链接,在此声明如有侵权请联系删除哈。

  • 9
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

涤生大数据

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值