# 類與對象的方法
我們已經討論了類與對象的功能部分,現在我們來看一下它的數據部分。事實上,它們只是與類和對象的**名稱空間** 綁定 的普通變量,即這些名稱只在這些類與對象的前提下有效。
有兩種類型的 域 ——類的變量和對象的變量,它們根據是類還是對象 擁有 這個變量而區分。
類的變量 由一個類的所有對象(實例)共享使用。只有一個類變量的拷貝,所以當某個對象對類的變量做了改動的時候,這個改動會反映到所有其他的實例上。
對象的變量 由類的每個對象/實例擁有。因此每個對象有自己對這個域的一份拷貝,即它們不是共享的,在同一個類的不同實例中,雖然對象的變量有相同的名稱,但是是互不相關的。通過一個例子會使這個易于理解。
```
#!/usr/bin/python
# Filename: objvar.py
class Person:
????'''Represents a person.'''
????population = 0
????def __init__(self, name):
????????'''Initializes the person's data.'''
????????self.name = name
????????print '(Initializing %s)' % self.name
????????# When this person is created, he/she
????????# adds to the population
????????Person.population += 1
????def __del__(self):
????????'''I am dying.'''
????????print '%s says bye.' % self.name
????????Person.population -= 1
????????if Person.population == 0:
????????????print 'I am the last one.'
????????else:
????????????print 'There are still %d people left.' % Person.population
????def sayHi(self):
????????'''Greeting by the person.
????????Really, that's all it does.'''
????????print 'Hi, my name is %s.' % self.name
????def howMany(self):
????????'''Prints the current population.'''
????????if Person.population == 1:
????????????print 'I am the only person here.'
????????else:
????????????print 'We have %d persons here.' % Person.population
swaroop = Person('Swaroop')
swaroop.sayHi()
swaroop.howMany()
kalam = Person('Abdul Kalam')
kalam.sayHi()
kalam.howMany()
swaroop.sayHi()
swaroop.howMany()
```
(源文件:[code/objvar.py](code/objvar.py))
## 輸出
```
$ python objvar.py
(Initializing Swaroop)
Hi, my name is Swaroop.
I am the only person here.
(Initializing Abdul Kalam)
Hi, my name is Abdul Kalam.
We have 2 persons here.
Hi, my name is Swaroop.
We have 2 persons here.
Abdul Kalam says bye.
There are still 1 people left.
Swaroop says bye.
I am the last one.
```
## 它如何工作
這是一個很長的例子,但是它有助于說明類與對象的變量的本質。這里,`population`屬于`Person`類,因此是一個類的變量。`name`變量屬于對象(它使用`self`賦值)因此是對象的變量。
觀察可以發現`__init__`方法用一個名字來初始化`Person`實例。在這個方法中,我們讓`population`增加`1`,這是因為我們增加了一個人。同樣可以發現,`self.name`的值根據每個對象指定,這表明了它作為對象的變量的本質。
記住,你**只**能使用`self`變量來參考同一個對象的變量和方法。這被稱為 屬性參考 。
在這個程序中,我們還看到**docstring**對于類和方法同樣有用。我們可以在運行時使用`Person.__doc__`和`Person.sayHi.__doc__`來分別訪問類與方法的文檔字符串。
就如同`__init__`方法一樣,還有一個特殊的方法`__del__`,它在對象消逝的時候被調用。對象消逝即對象不再被使用,它所占用的內存將返回給系統作它用。在這個方法里面,我們只是簡單地把`Person.population`減`1`。
當對象不再被使用時,`__del__`方法運行,但是很難保證這個方法究竟在 什么時候 運行。如果你想要指明它的運行,你就得使用`del`語句,就如同我們在以前的例子中使用的那樣。
給C++/Java/C#程序員的注釋
Python中所有的類成員(包括數據成員)都是 公共的 ,所有的方法都是 有效的 。
只有一個例外:如果你使用的數據成員名稱以 雙下劃線前綴 比如`__privatevar`,Python的名稱管理體系會有效地把它作為私有變量。
這樣就有一個慣例,如果某個變量只想在類或對象中使用,就應該以單下劃線前綴。而其他的名稱都將作為公共的,可以被其他類/對象使用。記住這只是一個慣例,并不是Python所要求的(與雙下劃線前綴不同)。
同樣,注意`__del__`方法與 destructor 的概念類似。
- 版權信息
- 前言
- 本書的由來
- 本書目前的狀況
- 約定條款
- 反饋
- 值得思考的一些東西
- 第1章 介紹
- Python的特色
- 為什么不使用Perl?
- 程序員的話
- 第2章 安裝Python
- Windows?用戶
- 概括
- 第3章 最初的步驟
- 使用帶提示符的解釋器
- 挑選一個編輯器
- 使用源文件
- 可執行的Python程序
- 獲取幫助
- 概括
- 第4章 基本概念
- 數
- 字符串
- 變量
- 標識符的命名
- 數據類型
- 對象
- 邏輯行與物理行
- 縮進
- 概括
- 第5章 運算符與表達式
- 運算符
- 運算符優先級
- 表達式
- 概括
- 第6章 控制流
- if語句
- while語句
- for循環
- break語句
- continue語句
- 概括
- 第7章 函數
- 函數形參
- 局部變量
- 默認參數值
- 關鍵參數
- return語句
- DocStrings
- 概括
- 第8章 模塊
- 字節編譯的.pyc文件
- from..import語句
- 模塊的name
- 制造你自己的模塊
- dir()函數
- 概括
- 第9章 數據結構
- 列表
- 元組
- 字典
- 序列
- 參考
- 更多字符串的內容
- 概括
- 第10章 解決問題——編寫一個Python腳本
- 解決方案
- 軟件開發過程
- 概括
- 第11章 面向對象的編程
- self
- 類
- 對象的方法
- __init__方法
- 類與對象的方法
- 繼承
- 概括
- 第12章 輸入/輸出
- 儲存器
- 概括
- 第13章 異常
- try..except
- 引發異常
- try..finally
- 概括
- 第14章 Python標準庫
- sys模塊
- os模塊
- 概括
- 第15章 更多Python的內容
- 單語句塊
- 列表綜合
- 在函數中接收元組和列表
- lambda形式
- exec和eval語句
- assert語句
- repr函數
- 概括
- 第16章 接下來學習什么?
- 探索更多內容
- 概括
- 附錄A 自由/開放源碼軟件(FLOSS)
- 附錄B 關于本書
- 關于作者
- 關于譯者
- 關于簡體中文譯本
- 附錄C 修訂記錄
- 術語表