python私有属性单、双下划线区别


私有属性是将变量作为私有的来使用:

  • 单下划线私有属性,其要求只有类本身和子类自己能访问到这些变量
  • 双下划线私有属性,其要求只有类本身能访问、子类不能访问
  • 通过以下方式可以在外部调用私有属性

1、单下划线与双下划线外部调用区别

单下划线私有属性可在外部通过实例直接调用,双下滑线私有属性可在外部通过【_类名__私有属性名】调用

import time, traceback


class People1:
    province = '河北'
    _city = "保定"
    __county = '曲阳'

    def __init__(self, name, age, gender):
        self.name = name
        self._age = age
        self.__gender = gender

    def info(self):
        print("这是实例方法")
        print('%s 是类属性' % self.province)
        print('%s 是私有类属性1' % self._city)
        print('%s 是私有类属性2' % self.__county)

        print('%s 是实例属性' % self.name)
        print('%s 是私有实例属性1' % self._age)
        print('%s 是私有实例属性2' % self.__gender)


def test1():
    print('验证1:私有属性的单下划线与双下划线,在外部调用时区别')
    person1 = People1("Mary", '18', '女')
    print("单下划线外部调用结果:%s" % person1._age)
    try:
        time.sleep(1)
        print(person1.__gender)
    except Exception as e:
        print("双下划线直接调用异常:")
        traceback.print_exc()
        time.sleep(1)
    print("双下划线正确外部调用方式(_类名__私有属性名):%s" % person1._People1__gender)
    print("该实例所有属性与方法:%s" % dir(person1))


test1()
验证1:私有属性的单下划线与双下划线,在外部调用时区别
单下划线外部调用结果:18
双下划线直接调用异常:
Traceback (most recent call last):
  File "/Users/yxt/Desktop/MyProjects/OsTest/test4.py", line 31, in test1
    print(person1.__gender)
AttributeError: 'People1' object has no attribute '__gender'
双下划线正确外部调用方式(_类名__私有属性名):女
该实例所有属性与方法:['_People1__county', '_People1__gender', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_age', '_city', 'info', 'name', 'province']

2、父类与子类的双下划线私有属性外部调用时区别

父类双下划线私有属性通过【_父类名__私有属性名】调用;

子类双下划线私有属性通过【_子类名__私有属性名】调用,

class Man(People1):
    def __init__(self, name, age, gender, phone):
        super(Man, self).__init__(name, age, gender)
        self._age = '100'
        self.__phone = phone

    def func(self):
        print('func')


def test2():
    print('验证2:父类的双下划线私有属性与子类的双下划线私有属性,在调用时区别')
    man = Man('john', '40', '男', '13633088809')
    print("父类的双下划线私有属性调用方式(_父类名__私有属性名):%s" % man._People1__gender)
    print("子类的双下划线私有属性调用方式(_子类名__私有属性名):%s" % man._Man__phone)


test2()
验证2:父类的双下划线私有属性与子类的双下划线私有属性,在调用时区别
父类的双下划线私有属性调用方式(_父类名__私有属性名):男
子类的双下划线私有属性调用方式(_子类名__私有属性名):13633088809

3、super方法继承父类,验证生成属性与方法的顺序

super方法继承父类,验证生成属性与方法的顺序

class Woman(People1):
    def __init__(self, name, age, gender, phone):
        print('生成实例,包含父类的类属性,父类与子类的函数:')
        print(dir(self))
        print('绑定父类的实例属性:')
        super(Woman, self).__init__(name, age, gender)  # 继承父类
        print(dir(self))
        print('绑定子类的实例属性')
        self.phone = phone
        print(dir(self))

    def func(self):
        print('func')


def test3():
    print('验证3:super方法继承父类(super在定义子类实例属性之前),验证生成属性的顺序')
    woman = Woman('Kate', '50', '女', '15010689376')


test3()
验证3:super方法继承父类(super在定义子类实例属性之前),验证生成属性的顺序
生成实例,包含父类的类属性,父类与子类的函数:
['_People1__county', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_city', 'func', 'info', 'province']
绑定父类的实例属性:
['_People1__county', '_People1__gender', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_age', '_city', 'func', 'info', 'name', 'province']
绑定子类的实例属性
['_People1__county', '_People1__gender', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_age', '_city', 'func', 'info', 'name', 'phone', 'province']

4、类属性、私有属性的内存存储

类属性与实例属性区别:类属性在内存只有一个,即类作为对象只初始化一次;实例属性在内存有多个,即每个实例都有对应的实例属性

def test4():
    print('验证4:在创建类时生成类属性,在创建实例时生成实例属性')
    person1 = People1("Mary", '18', '女')
    person2 = People1("Jack", '16', '男')
    print("%s 与 %s 对比:类属性【省份】内存地址【%s】、实例属性【姓名】内存地址【%s】" % (
        person1.name, person2.name, "相等" if id(person1.province) == id(person2.province) else "不相等", "相等" if id(person1.name) == id(person2.name) else "不相等"))


test4()
验证4:在创建类时生成类属性,在创建实例时生成实例属性
Mary 与 Jack 对比:类属性【省份】内存地址【相等】、实例属性【姓名】内存地址【不相等】
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值