Python 面向对象 补充 属性相关

私有化属性

Python 并没有真正的私有化支持,但是可以使用下划线完成伪私有化的效果。
类属性和实例属性遵循相同的规则。

x

公有属性

  • 类内部访问
  • 子类内部访问
  • 模块内其他位置访问
    • 类访问
    • 实例访问
  • 跨模块访问
    • import 形式导入
    • from 模块 import * 形式导入
class Animal:
    x = 10
    def test(self):
        print(Animal.x)
        print(self.x)


class Dog(Animal):
    def test2(self):
        print(Dog.x)
        print(self.x)

a = Animal()
a.test()

d = Dog()
d.test2()

print(Animal.x)


_y

受保护属性

  • 类内部访问
  • 子类内部访问
  • 模块内其他位置访问
    • 类访问
    • 实例访问
  • 跨模块访问
    • import 形式导入
    • from 模块 import * 形式导入, 有__all__指明对应变量
class Animal:
    _x = 10
    def test(self):
        print(Animal._x)
        print(self._x)


class Dog(Animal):
    def test2(self):
        print(Dog._x)
        print(self._x)

a = Animal()
a.test()

d = Dog()
d.test2()

print(Animal._x)

__all__ = ['_a']

_a = 666

__z

私有属性

  • 类内部访问
  • 跨模块访问
    • import 形式导入
    • from 模块 import * 形式导入, 有__all__指明对应变量
class Animal:
    __x = 10
    def test(self):
        print(Animal.__x)
        print(self.__x)

a = Animal()
a.test()

__all__ = ['__a']

_a = 666

私有属性的实现机制:名字重整(Name Mangling), 重改__x为另外一个名称,如_类名__x
目的:防止外界直接访问,防止被子类同名称属性覆盖

class Person:
    # 创建好一个实例对象之后,会自动的调用这个方法,来初始化这个对象
    def __init__(self):
        self.__age = 18
    
    def setAge(self, value):
        if isinstance(value, int) and 0 < value < 200:
            self.__age = value
        else:
            print('数据有问题')
    
    def getAge(self):
        return self.__age

p1 = Person()
p1.setAge(20)

print(p1.getAge())

补充

xx_

用于区分关键字

__xx__

系统内置

只读属性

一个属性(一般指实例属性),只能读取,不能写入
有些属性,只限于内部根据不同场景进行修改,而对外界来说,不能修改,只能读取

方式1

全部隐藏,私有化,既不能读,也不能写。
部分公开,公开读的操作。
私有化:通过属性前置双下划线实现。
部分公开:通过公开的方法。

class Person:
    # 创建好一个实例对象之后,会自动的调用这个方法,来初始化这个对象
    def __init__(self):
        self.__age = 18
    
    def getAge(self):
        return self.__age

p1 = Person()

print(p1.getAge())

优化:
property
将一些属性的操作方法关联到某一个属性中

class Person(object):
    # 创建好一个实例对象之后,会自动的调用这个方法,来初始化这个对象
    def __init__(self):
        self.__age = 18
    
    # 主要作用就是,可以以使用属性的方式,来使用这个方法
    @property
    def age(self):
        return self.__age

p1 = Person()

print(p1.age)

property

概念补充:
经典类:没有继承(object)
新式类:继承(object)
python3 默认新式类,会隐式的继承object。
建议使用新式类。

class Person:
    pass

print(Person.__bases__)

(<class ‘object’>,)

class Person(object):
    pass

print(Person.__bases__)

(<class ‘object’>,)

class Person(object):
    def __init__(self):
        self.__age = 18
    
    def get_age(self):
        print('---, get')
        return self.__age
    
    def set_age(self, value):
        print('---, set')
        self.__age = value
    
    age = property(get_age, set_age)

p = Person()
print(p.age)

p.age = 90

print(p.age)

—, get
18
—, set
—, get
90

class Person(object):
    def __init__(self):
        self.__age = 18
    
    @ property
    def age(self):
        print('---, get')
        return self.__age

    @age.setter
    def age(self, value):
        print('---, set')
        self.__age = value
    

p = Person()
print(p.age)

p.age = 90

print(p.age)

—, get
18
—, set
—, get
90

方式2

class Person(object):
    # 当我们通过 实例.属性 = 值,给一个实例增加一个属性,或者修改一个属性值的时候,都会调用这个方法
    # 在这个方法内部,才会真正的把这个属性以及对应的数据,给存储到__dict__字典里面
    def __setattr__(self, key, value):
        print(key, value)
        # 判定 key 是否是我们要设置的只读属性
        if key == 'age' and key in self.__dict__.keys():
            print('这个属性是只读属性')
        else:
        # 如果不是只读属性的名称,添加到这个实例里面
            self.__dict__[key] = value


p1 = Person()
p1.age = 18
print(p1.age)
p1.age = 999
print(p1.age)

print(p1.__dict__)

age 18
18
age 999
这个属性是只读属性
18
{‘age’: 18}

内置特殊属性

类属性:

class Person(object):
    """
    文档说明
    """
    age = 19
    def __init__(self):
        self.name = 'sz'

    def run(self):
        print('run')

# 类的属性
print(Person.__dict__)
# 类的所有父类构成元组
print(Person.__bases__)
# 类的文档字符串
print(Person.__doc__)
# 类名
print(Person.__name__)
# 类定义所在的模块
print(Person.__module__)

# 实例对应的类
p = Person()
print(p.__class__)

{‘module’: ‘main’, ‘doc’: '\n 文档说明\n ', ‘age’: 19, ‘init’: <function Person.init at 0x041F0738>, ‘run’: <function Person.run at 0x041F0780>, ‘dict’: <attribute ‘dict’ of ‘Person’ objects>, ‘weakref’: <attribute ‘weakref’ of ‘Person’ objects>}
(<class ‘object’>,)

文档说明

Person
main
<class ‘main.Person’>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值