# 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)