Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说python的动态性_python中@property「建议收藏」,希望能够帮助你!!!。
在讲这个property动态属性之前,先来看一下我们司空见惯的一行代码:
if __name__ == '__main__': pass
有时候你可能觉得把代码写在main语句里面太麻烦了,直接运行也是可以的,的确如此,但是这个main方法真的有用,因为它可以选择性执行代码。下面举个例子,在A.py文件中写入这行代码,然后在B.py中引用这行代码,你直接运行B.py文件这段代码就会被执行。这也仅仅是一行代码,如果几千几万行代码呢?我们需要的那段代码还没运行,程序可能就已经卡死了。
print("my info in {}".format(__file__))
但是如果你将这段代码放在main语句里面,你会发现此时运行B.py文件这段代码就不再执行了,因此推荐使用这种。继续我们property动态属性的介绍。
先看一段代码:
from datetime import date,datetime class User(object): def __init__(self, name, birthday, sex): self.name = name self.birthday = birthday self.sex = sex self._age = 0 # 此处的单下划线并不是私有属性,只是给人一种特殊的感觉,只有__双下化线Python才是私有变量 # def get_age(self): # # print(self.birthday.year) # return datetime.now().year-self.birthday.year @property def age(self): return datetime.now().year - self.birthday.year @age.setter def age(self, value): self._age = value # print("my info in {}".format(__file__)) if __name__ == '__main__': user = User("envy", date(year=2008, month=8, day=8), "男") # print(user.get_age()) print(user.age) user._age = 20 print(user._age)
一般存入数据库的是年龄,但是我们又不能直接传入年龄,因为时间在改变,年龄也会变,以后更新会很难。我们可以新建一个方法,处理一下年龄不就可以么?。但是我们在设计数据库的时候是有一个age字段的,因此考虑不通过调用user.get_age()这种方式,最好是user.age方式呢?可以的,此时property动态属性就派上用场了,简单一点就是property可以将函数调用变为属性调用,而且在内部可以增加自己的逻辑,不过这个property只是一种getter方法,那么有没有setter方法呢?可以,因为你已经get到了age的值,当然就可以对其进行操作了。
不知道这样介绍是不是很好理解,我觉得还是有必要再详细一点,再来看一个例子,这个例子非常常见:获取学生的成绩。成绩都只有在考试之后才有的,因此你实例化一个学生的时候,一般就是姓名,学号,以及科目,为了简化此处只假设学生初始化只有姓名这一个属性,后续也只增加成绩这个属性,多的没有必要。
class Student: def __init__(self, name): self.name = name self._score = None # 此处写self.score = None 也可以 test= Student('test')
考试只后,test这位同学的成绩出来了98分,不过老师不小心多打了一个8,变成988分。这个可以理解毕竟学生太多,老师打分出现纰漏的情况可能会出现,所以我们想限制分数值必须在 0-100 分之间(百分制)。
test.score = 988
最简单的方式就是定义一个可以检查分数的函数:
def set_score(self, new_score): if not isinstance(new_score, int): raise ValueError("对不起,分数必须是整数") if 0 <= new_score <=100: self._score = new_score else: raise ValueError("对不起,分数必须在0-100之间")
然后直接调用这个方法进行分数赋值,这的确可以检查赋值的分数是否满足要求,但是我们依然可以使用self._score=98进行赋值。尽管Python中提供了私有属性,但这其实是伪私有(_ 开头),只是一种协议和规定,不推荐去访问以下划线开头的属性,但这并不表示不能访问。那么这样,使用prperty动态属性就能解决这个问题,因为它将函数调用转为属性调用。
property动态属性只是类似于getter方法,可以使用方法名.setter达到setter的目的
class Student: def __init__(self, name): self.name = name self._score = None @property def score(self): return self._score @score.setter def score(self, new_score): if not isinstance(new_score, int): raise ValueError("对不起,分数必须是整数") if 0 <= new_score <= 100: self._score = new_score return self._score else: raise ValueError("对不起,分数必须在0-100之间") if __name__ == '__main__': test = Student("test") test.score = 98
当然其实这里你还是可以使用self._score=98进行赋值,不过大家都不会这么干,因为这里已经有self.score=98了,谁还会在前面多加一横呢?
总结一下:
@property 优化了属性读取和设置的可读性,一般用于需要限制属性的特征的场合;它是只读属性。如果属性只读,不可以写,此时用它是最合适不过了,并且记住这个属性会根据环境而动态改变。(property一般都有返回值,正如Java中的getter和setter方法一样,前者有返回值,后者没有)
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。