【Python面向对象——属性访问Attribute Access】

目录

直接访问

Getters和Setters

property()

@property

私有属性__name

类属性和对象属性


在Python中,对象属性和方法通常是public的。

直接访问

class Duck:
    def __init__(self, input_name):
        self.name = input_name

if __name__ == "__main__":
    fowl = Duck('Daffy')
    print(fowl.name)
    fowl.name = 'Daphne'
    print(fowl.name)

# ======输出======= #
Daffy
Daphne

如果希望对属性设置一些私密性,可以使用下面方法:

Getters和Setters

对于面向对象中一些私有对象属性,是不能由类外访问的,程序员需要写一些读取属性或设定属性的函数。

Python并没有私有属性,但是可以写getters和setters来实现私有。

class Duck:
    def __init__(self, input_name):
        self.hidden_name = input_name
    def get_name(self):
        print("Inside the getter.")
        return self.hidden_name
    def set_name(self, input_name):
        print("Inside the setter.")
        self.hidden_name = input_name

if __name__ == "__main__":
    fowl = Duck('Daffy')
    print(fowl.get_name())
    fowl.set_name("Daphne")
    print(fowl.get_name())

# ======输出======= #
Inside the getter.
Daffy
Inside the setter.
Inside the getter.
Daphne

property()

class Duck:
    def __init__(self, input_name):
        self.hidden_name = input_name
    def get_name(self):
        print("Inside the getter.")
        return self.hidden_name
    def set_name(self, input_name):
        print("Inside the setter.")
        self.hidden_name = input_name
    name = property(get_name, set_name)

if __name__ == "__main__":
    fowl = Duck('Daffy')
    print(fowl.get_name())
    fowl.set_name("Daphne")
    print(fowl.get_name(), '\n')
    don = Duck('Donald')
    print(don.name)
    don.name = 'Donna'
    print(don.name)

# ======输出======= #
Inside the getter.
Daffy
Inside the setter.
Inside the getter.
Daphne 

Inside the getter.
Donald
Inside the setter.
Inside the getter.
Donna

@property

class Duck:
    def __init__(self, input_name):
        self.hidden_name = input_name
    @property
    def name(self):
        print("Inside the getter.")
        return self.hidden_name
    @name.setter
    def name(self, input_name):
        print("Inside the setter.")
        self.hidden_name = input_name

if __name__ == "__main__":
    fowl = Duck('Daffy')
    print(fowl.name)
    fowl.name = "Daphne"
    print(fowl.name)

# ======输出======= #
Inside the getter.
Daffy
Inside the setter.
Inside the getter.
Daphne

也可以用于计算数值,可以像类有radius属性一样以属性方式调用diameter函数。且当我们改变radius属性后,diameter也会跟着改变。如果没有指定属性的setter property,就不能在外部设定值。

class Circle():
    def __init__(self, radius):
        self.radius = radius
    @property
    def diameter(self):
        return 2 * self.radius

if __name__ == "__main__":
    c = Circle(5)
    print(c.radius)
    print(c.diameter)
    c.radius = 7
    print(c.radius)
    print(c.diameter)
    c.diameter = 20

# =====输出===== #
5
10
7
14
Error: .... can't set attribute

对直接属性访问,使用property的另一个好处是,如果改变了属性的定义,只需要更改类定义中的代码,不用修改所有函数中的属性。

私有属性__name

Python对于类定义外不可见的属性命名有一个传统,即__name(双下划线在前)。

class Duck():
    def __init__(self, input_name):
        self.__name = input_name
    @property
    def name(self):
        print("Inside the getter.")
        return self.__name
    @name.setter
    def name(self, input_name):
        print("Inside the setter.")
        self.__name = input_name

if __name__ == '__main__':
    fowl = Duck('Howard')
    print(fowl.name)
    fowl.name = 'Donald'
    print(fowl.name)
    print(fowl._Duck__name)  # 还是能打印出来的
    print(fowl.__name)

# =====输出===== #
Inside the getter.
Howard
Inside the setter.
Inside the getter.
Donald
Donald
Error: ...

尽管这个命名传统并不是使属性完全private,但Python让属性名不太可能被外部代码改变。

类属性和对象属性

可以给类属性赋值,这个值会被对象继承。

如果改变对象的属性值,不会影响类的属性值。

如果后续改变了类的属性值,不会影响已经存在的对象的属性值,但是会影响新建的对象属性值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值