python property setter_Python:动态属性 property & setter 以及 __getattr__ 属性

1. property

引言:

-- 假设有这样一个需求,我们需要创建一个 User 类,并初始化 birthday 参数,之后根据 birthday 计算得到年龄;

-- 我们设计下面的代码实现该需求:

>>> from datetime import date, datetime

>>>

>>>

>>> class User():

... def __init__(self, nbirthday):

... self.birthday = birthday

... def get_age(self):

... return datetime.now().year - self.birthday.year

...

>>>

>>> user = User(date(year=1990, month=3, day=5))

>>> age = user.get_age()

>>> print(age)

30

-- 上面的代码中使用 user 实例调用 get_age() 方法获取 age,但是这种方法并不是常规方法,我们习惯用类似于 user.age 这样的方式获取 age;

property

-- 于是我们引入 property 属性,将 age() 方法变为实例的一个 age 属性,这样就可以通过 user.age 直接调用,代码如下:

>>> from datetime import date, datetime

>>>

>>>

>>> class User():

... def __init__(self, birthday):

... self.birthday = birthday

... @property

... def age(self):

... return datetime.now().year - self.birthday.year

...

>>>

>>> user = User(date(year=1990, month=3, day=5))

>>> print(user.age)

30

2. setter

引言

-- 假设有这样一个需求,我们需要创建一个 User 类,初始化属性 age 默认为 0,之后改变 age 的值,并获取该值;

-- 我们设计下面的代码实现该需求:

>>> class User():

... def __init__(self):

... self.age = 0

... def set_age(self, age):

... self.age = age

...

>>>

>>> user = User("zhang")

>>> user.set_age(30)

>>> print(user.age)

30

-- 上面的代码中使用 user 实例调用 set_age() 方法赋值于 age,但是这种方法并不是常规方法,我们习惯用类似于 user.age = xxx 这样的方式赋值 age;

setter

-- 于是我们引入 setter 属性,这样就可以通过 user.age 直接赋值,代码如下:

>>> class User():

... def __init__(self,):

... self._age = 0

... @ property

... def age(self):

... return self._age

... @age.setter

... def age(self, age_value):

... self._age = age_value

...

>>>

>>> user = User()

>>> user.age = 30

>>> print(user.age)

30

3. __ getattr __

引言

-- 在开发过程中,我们经常需要设计并获取类的实例对象的属性,但有时会因为疏忽遗漏没有为类设计某个属性,这就导致获取属性值的实收出现报错,故而造成程序异常甚至崩溃;

-- 如下面的代码:

>>> class User():

... def __init__(self, name):

... self.name = name

...

>>>

>>> user = User(name="zhangsan")

>>> print(user.age)

Traceback (most recent call last):

File "", line 1, in

AttributeError: 'User' object has no attribute 'age'

__ getattr __ 处理 object has no attribute 报错

-- 如上面的代码,User 类并没有 age 属性,所以在实例 user 获取 age 属性时遇到报错,这个时候需要用到 __ getattr __ 解决此问题;

>>> class User():

... def __init__(self, name):

... self.name = name

... def __getattr__(self, item): # 注意:此处 item 不能少

... pass

...

>>>

>>> user = User(name="zhangsan")

>>> print(user.age)

None

-- 在上面的代码中,User 类并没有 age 属性,所以在实例 user 获取 age 属性时并未报错,而只是反悔了一个 None,这就有效避免了报错;

__ getattr __ 获取 dict 类型属性的 value 值

-- 除了上面的用法,__ getattr __ 还可以用来更好的获取 dict 类型属性的 value 值;

-- 比如我们初始化类时给与其一个 dict 字典属性参数,我们希望可以通过 实例. 属性(比如 user.age)的方式直接获取 dict 字典中 key 为 age 的 value 值;

-- 以下面的代码为例:

>>> class User():

... def __init__(self, info={}):

... self.info = info

... def __getattr__(self, item):

... if not item in self.info.keys():

... return None

... return self.info[item]

...

>>>

>>> user = User({"name":"zhangsan", "age":23})

>>> print(user.age)

23

>>> print(user.gender)

None

-- 代码中 user.age 的方式直接获取初始化参数 dict 字典中 key 为 age 的 value 值 23,同时 dict 中并未有 key 为 gender 的键值对,user.gender 直接返回 None 而并未出现报错;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值