# go/python-tips/058 ## Instance Attribute v.s. Class Attribute 實體屬性(Instance Attribute) -> color 類別屬性(Class Attribute) -> door ``` python class Cars: door = 4 def __init__(self): self.color = "blue" mazda = Cars() toyota = Cars() print(f"mazda.door = {mazda.door}, mazda.color = {mazda.color}") print(f"toyota.door = {toyota.door}, toyota.color = {toyota.color}") mazda.color = "red" Cars.door = 2 print(f"mazda.door = {mazda.door}, mazda.color = {mazda.color}") print(f"toyota.door = {toyota.door}, toyota.color = {toyota.color}") ``` ``` bash mazda.door = 4, mazda.color = blue toyota.door = 4, toyota.color = blue mazda.door = 2, mazda.color = red toyota.door = 2, toyota.color = blue ``` ## Problem ``` python >>> class Cars: ... door = 4 ... def __init__(self): ... self.color = "blue" >>> mazda = Cars() >>> mazda.door = -1 >>> >>> mazda.door -1 ``` ## Problems!!! ``` python >>> class Money: ... def __init__(self): ... self._ratio = 30 ... def change_to_NTD(self, value): ... return value * self._ratio >>> US_dollar = Money() >>> print(US_dollar.change_to_NTD(100)) 3000 >>> >>> US_dollar._ratio = 20 >>> print(US_dollar.change_to_NTD(100)) 2000 ``` ## What do we want? ``` python >>> chiawei = People() >>> print(f"chiawei.age = {chiawei.age}") chiawei.age = 1 >>> chiawei.age = 98 >>> print(f"chiawei.age = {chiawei.age}") chiawei.age = 98 >>> chiawei.age = -3 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 12, in age ValueError: I believe the age is incorrect. ``` ## Traditional Method (Get, Set) ``` python chiawei.get_age() chiawei.set_age(98) ``` ``` python class People: def __init__(self, value=1): self.__age = value def get_age(self): return self.__age def set_age(self, value): if 0 <= value < 150: self.__age = value else: raise ValueError("I believe the age is incorrect.") chiawei = People() print(f"chiawei.age = {chiawei.get_age()}") chiawei.set_age(98) print(f"chiawei.age = {chiawei.get_age()}") chiawei.set_age(-3) print(f"chiawei.age = {chiawei.get_age()}") ``` ## Read Only ``` python >>> chiawei = People() >>> print(f"chiawei.age = {chiawei.age}") chiawei.age = 1 >>> chiawei.age = 98 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: can't set attribute 'age' >>> print(f"chiawei.age = {chiawei.age}") chiawei.age = 1 ``` ## Property ``` python class People: def __init__(self, value=1): self.__age = value @property def age(self): return self.__age @age.setter def age(self, value): if 0 <= value < 150: self.__age = value else: raise ValueError("I believe the age is incorrect.") ``` # Reference * [[Python教學] @property是什麼? 使用場景和用法介紹](https://www.maxlist.xyz/2019/12/25/python-property/) * [這是什麼妖術?Python 的屬性 (property) 運作原理](https://dev.to/codemee/zhe-shi-shi-mo-yao-shu-python-de-shu-xing-property-yun-zuo-yuan-li-3fna) * [[Python物件導向]3個必須瞭解的Python屬性觀念](https://www.learncodewithmike.com/2020/01/python-attribute.html) * [python @property的介绍与使用](https://zhuanlan.zhihu.com/p/64487092)