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