### Color類
從一個非常簡單的類定義開始:
~~~
class Color(object):
'''An RGB color,with red,green,blue component'''
pass
~~~
關鍵字def用于告訴Python我們定義了一個新函數,關鍵字class則表明我們定義了一個新類。(object)這部分內容說的是,類Color是一種對象;文檔字符串描述了Color對象的功能,pass則說明該對象是空白的(即為存放任何數據,也沒有提供任何的新操作)。使用方式如下:
~~~
>>> black = Color()
>>> black.red = 0
0
>>> black.green = 0
0
>>> black.blue = 0
0
~~~
### 方法
根據定義,顏色亮度就是其最強和最弱的RGB值得平均值對應到0和1之間的那個數值。若寫成函數,如下所示:
~~~
def lightness(color):
'''Return the lightness of color.'''
strongest = max(color.red, color.green, color.blue)
weakest = min(color.red, color.green, color.blue)
return 0.5 * (strongest + weakest) / 255
~~~
若將函數`lightness()`作為Color類的一個方法,如下所示:
~~~
class Color(object):
'''An RGB color,with red,green,blue component'''
def lightness(self):
'''Return the lightness of color.'''
strongest = max(self.red, self.green, self.blue)
weakest = min(self.red, self.green, self.blue)
return 0.5 * (strongest + weakest) / 255
~~~
需要移除參數color,并將其替換成self參數。當Python在調用某個對象中的某個方法時,會自動將該對象的引用作為該方法的第一個參數傳進去。這就意味著,當我們調用lightness時,完全不需要給它傳遞任何參數。使用方式如下:
~~~
>>> purple = Color()
>>> purple.red = 255
>>> purple.green = 0
>>> purple.blue = 255
>>> purple.lightness()
0.5
~~~
**定義一個方法的時候,除了實際需要傳入的那些參數之外,還必須再多寫一個。相反,在調用某個方法的時候,實際提供的參數要比該方法定義中所需的少一個。**
### 構造器
給Color類添加一個當創建新Color的時候就會被執行的方法。這種方法叫做構造器(constructor);在Python中,構造器就是__init__:
~~~
class Color(object):
'''An RGB color,with red,green,blue component'''
def __init__(self, r, g, b):
'''A new color with red value r, green value g, and blue value b. All
components are integers in the range 0-255.'''
self.red = r
self.green = g
self.blue = b
~~~
名稱兩邊的雙下劃線說明該方法對Python有著特殊的意義——這里的意思就是說,創建新對象的時候,該方法就會被調用。
~~~
purple = Color(128, 0, 128)
~~~
### 特殊方法
當需要從某個對象得到一段簡單易懂的信息時,就會調用__str__;當需要這段信息更準確時,則會調用__repr__。在使用print時,__str__就會被調用。為了得到有意義的輸出,現在來寫個`Color.__str__`:
~~~
class Color(object):
'''An RGB color,with red,green,blue component'''
def __init__(self, r, g, b):
'''A new color with red value r, green value g, and blue value b. All
components are integers in the range 0-255.'''
self.red = r
self.green = g
self.blue = b
def __str__(self):
'''Return a string representation of this Color in the form of an RGB tuple.'''
return'(%s, %s, %s)' %(self.red, self.green, self.blue)
~~~
Python中還有很多特殊方法:Python的官方網站上給出了完成的列表。其中就有__add__、__sub__、__eq__等,它們分別在我們用“+”對對象做加法,用“-”對對象做減法、用“==”對對象做比較的時候調用:
~~~
class Color(object):
'''An RGB color,with red,green,blue component'''
def __init__(self, r, g, b):
'''A new color with red value r, green value g, and blue value b. All
components are integers in the range 0-255.'''
self.red = r
self.green = g
self.blue = b
def __str__(self):
'''Return a string representation of this Color in the form of an RGB tuple.'''
return'(%s, %s, %s)' %(self.red, self.green, self.blue)
def __add__(self, other_color):
'''Return a new Color made from adding the red, green and blue components
of this Color to Color other_color's components. If the sum is greater than
255, the color is set to 255'''
return Color(min(self.red + other_color.red, 255),
min(self.green + other_color.green, 255),
min(self.blue + other_color.blue, 255))
def __sub__(self, other_color):
'''Return a new Color made from subtracting the red, green and blue components
of this Color to Color other_color's components. If the difference is less than
255, the color is set to 0'''
return Color(min(self.red - other_color.red, 0),
min(self.green - other_color.green, 0),
min(self.blue - other_color.blue, 0))
def __eq__(self, other_color):
'''Return True if this Color's components are equal to Color other_color's components.'''
return self.red == other_color.red and self.green == other_color.green \
and self.blue == other_color.blue
def lightness(self):
'''Return the lightness of color.'''
strongest = max(self.red, self.green, self.blue)
weakest = min(self.red, self.green, self.blue)
return 0.5 * (strongest + weakest) / 255
~~~
這些方法的具體用法:
~~~
purple = Color(128, 0, 128)
white = Color(255, 255, 255)
dark_grey = Color(50, 50, 50)
print(purple + dark_grey)
print(white - dark_grey)
print(white == Color(255, 255, 255))
~~~
可以使用`help(Color)`獲取有關Color類的幫助信息:
~~~
Help on Color in module __main__ object:
class Color(builtins.object)
| An RGB color,with red,green,blue component
|
| Methods defined here:
|
| __add__(self, other_color)
| Return a new Color made from adding the red, green and blue components
| of this Color to Color other_color's components. If the sum is greater than
| 255, the color is set to 255
|
| __eq__(self, other_color)
| Return True if this Color's components are equal to Color other_color's components.
|
| __init__(self, r, g, b)
| A new color with red value r, green value g, and blue value b. All
| components are integers in the range 0-255.
|
| __str__(self)
| Return a string representation of this Color in the form of an RGB tuple.
|
| __sub__(self, other_color)
| Return a new Color made from subtracting the red, green and blue components
| of this Color to Color other_color's components. If the difference is less than
| 255, the color is set to 0
|
| lightness(self)
| Return the lightness of color.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __hash__ = None
~~~
### 小結
- 在面向對象編程語言中,定義新類型的手段是:創建新類。類支持封裝,換句話說,類將數據以及相關的操作放在一起,以便使程序的其他部分可以忽略相關的實現細節。
- 類還支持多態。如果兩個類擁有相同用法的方法,則他們的實例可以互相替換,且不會影響到程序的其他部分。這就意味著我們能夠進行“即插即用型”編程,即代碼能夠根據所處理的具體類型而執行不同的操作。(多態的意思就是說,某個含有變量的表達式可以根據該變量所引用的對象的實際類型得到不同的結果。)
- 新類還可以通過“繼承現有類”的方式來進行定義:`class child(parent)`。系類不僅可以重寫父類的功能特點,而且還可以添加新的功能特點。
- 當方法被定義在類中時,其第一個參數必須是一個特殊的變量,該變量表示的是調用該方法的那個對象。按照慣例,這個參數成為self。
- 在Python中,部分方法擁有著特殊的預定義含義:為了有所區別,他們的名稱以雙下劃線開頭和結尾。在這些方法中,有的在構造對象時調用(__init__),有的在將對象轉換為字符串時調用(__str__和__repr__),有的則用于模擬算數運算(比如__add__和__sub__)。