---
# System prepended metadata

title: Class屬性

---

# Class

**類別屬性**
* 定義在類別層級的屬性(Attribute)，也就是在建構式(`__init__`)之外的屬性(Attribute)。可以不需要建立物件(Object)，直接透過類別名稱存取。
* 各物件共享類別屬性(Class Attribute)值，當修改類別屬性(Class Attribute)時，會影響此類別(Class)所建立的所有物件(Object)。

**實例屬性**
* 伴隨物件(Object)的生成來建立。
* 透過點(.)的語法或在建構式(`__init__`)中所生成的屬性(Attribute)。
* 各物件(Object)的實體屬性(Instance Attribute)各自獨立，修改某物件屬性不影響其他物件屬性。

`def __init__(self):`
**建構式**，代表宣告時會自動執行的函式。一般放基礎的屬性設定。

class的概念是屬性集合，而不是所有物。下面範例 動物.名字，意思是 名字是動物的屬性。
注意使用函式def 跟 屬性時，要加上預設參數 self，當作此實體。這樣呼叫函式時才會運作正常。
```python=
class Animal():
 def __init__(self, name):
  self.name = name

a = Animal("dog")  # 建立一個名叫dog的Animal實體(物件)
print(a.name)  
b = Animal()  # raise Error 因為沒有給name屬性
# dog
# TypeError: __init__() missing 1 required positional argument: 'name'
```

屬性前加底線( __ )變成私有變數，用來設定一些內部使用的函數，不能被一般方式讀取。__name不能被直接讀取。
```python=
class Animal():
  def __init__(self, name, age):
    self.__name = name
    self.age = age
    
a = Animal('dog',6)
print(a.age)  
print(a._Animal__name)  # 可用此方式讀取__屬性
print(a.__name)  
# 6
# dog，可用此方式讀取__屬性
# AttributeError: 'Animal' object has no attribute '__name'
```

Python任何類的實例都有一個`__dict__`來存儲實例的屬性。
有時只想使用固定的屬性，而不想任意綁定屬性，可以定義一個屬性名稱集合`__slots__`，只有在這集合裡的名稱才可以綁定。

```python=
class base(object):
    __slots__=('x')
    var = 1
    def __init__(self): pass

b = base()
b.x = 2
print(b.x)
print(b.__dict__)  # 有slots後 就不會創建dict
b.y = 3  # AttributeError: 'base' object has no attribute 'y' ，slots沒綁定的屬性 就不能添加到實例
# 2
# AttributeError: 'base' object has no attribute '__dict__' 
```

優點:
類的屬性固定的情況下，可以使用__slots__來優化內存。

**Reference:**
https://blog.csdn.net/sxingming/article/details/52892640