Python面向对象编程

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__)。
时间: 2024-09-14 07:34:07

Python面向对象编程的相关文章

【Python之旅】第四篇(三):Python面向对象编程详解

终于是来到了Python的面向对象编程,以前是没有接触过其它的面向对象编程的语言,因此学习这一部分是相当带劲的,这里也总结一下. 1.面向对象编程的相关名词及解释     世界万物,皆可分类,一切皆为对象.     所谓的面向对象编程,指的是一种编程的思想,通过对具体代码实现过程(面向过程编程)的不断抽象,以形成一个个的类别,以提高我们进行大型程序编写的效率(面向对象的具体实现需要面向过程,大型程序也可以用面向过程来编写,只是比较麻烦).对于面向对象编程的相关名词和解释如下: 对象 :类的实体\

《Python面向对象编程指南》——1.5 通过工厂函数调用__init()__

1.5 通过工厂函数调用__init()__ 我们可以使用工厂函数来完成所有Card对象的创建,这比枚举52张牌的方式好很多.在Python中,实现工厂有两种途径. 定义一个函数,返回不同类的对象. 定义一个类,包含了创建对象的方法.这是完整的工厂设计模式,正如设计模式书中提到的.在类似Java这样的语言里,工厂类层次结构是必需的,因为语言本身不支持可以脱离类而单独存在的函数. 在Python里,类定义不是必需的.仅当特别复杂的情形,工厂类才是不错的选择.Python的优势之一是,对于只需要简单

《Python面向对象编程指南》——导读

前 言 本书主要介绍Python语言的高级特性,特别是如何编写高质量的Python程序.这通常意味着编写高性能且拥有良好可维护性的程序.同时,我们也会探究不同的设计方案并确定究竟是哪种方案提供了最佳性能.而对于一些正在寻找解决方案的问题,这也是一种很好的方式. 本书的大部分内容将介绍一种给定设计的不同替代方案.一些方案性能更好,另一些方案更加简单或者更加适合于特定领域的问题.最重要的是,找到最好的算法和最优的数据结构,以最少的开销换取最大的价值.时间就是金钱,高效的程序会为它们的用户创造更多的价

《Python面向对象编程指南》——第1部分 用特殊方法实现Python风格的类 第1章 __init__()方法 1.1 隐式的基类——object

第1部分 用特殊方法实现Python风格的类 init()方法 与Python无缝集成--基本特殊方法 属性访问.特性和修饰符 抽象基类设计的一致性 可调用对象和上下文的使用 创建容器和集合 创建数值类型 装饰器和Mixins--横切方面 用特殊方法实现 Python风格的类 通过重写特殊方法来完成对Python内部机制的调用,在Python中是很普遍的.例如len()函数就可以重写一个类的__len__()方法. 这意味着对于像(len(x))这样的通用公共接口,任何类(例如,声明一个类叫ti

《Python面向对象编程指南》——1.7 简单的组合对象

1.7 简单的组合对象 一个组合对象也可以称作容器.我们会从一个简单的组合对象开始介绍:一副牌.这是一个基本的集合对象.我们的确可以简单地使用一个list来代替一副牌(deck)对象. 在设计一个类之前,我们需要考虑这样的一个问题:简单地使用list是合适的做法吗? 可以使用random.shuffle()函数完成洗牌操作,使用deck.pop()来完成发牌操作. 一些程序员可能会过早定义新类,正如像使用内置类一样,违反了一些面向对象的设计原则.比如像下面的这个设计. d= [card6(r+1

《Python面向对象编程指南》——1.12 更多的__init__()技术

1.12 更多的__init__()技术 我们再来看一下其他一些更高级的__init__()技术的应用.相比前面的介绍,它们的应用场景不是特别常见. 以下是Player类的定义,初始化使用了两个策略对象和一个table对象.这个__init__()函数看起来不够漂亮. class Player: def __init__( self, table, bet_strategy, game_strategy ): self.bet_strategy = bet_strategy self.game_

《Python面向对象编程指南》——2.8 __new__()方法和不可变对象

2.8 __new__()方法和不可变对象 __new__方法的一个用途是初始化不可变对象.__new__()方法中允许创建未初始化的对象.这允许我们在__init__()方法被调用之前先设置对象的属性. 由于不可变类的__init__()方法很难重载,因此__new__方法提供了一种扩展这种类的方法. 下面是一个错误定义的类,我们定义了float的一个包含单位信息的版本. class Float_Fail( float ): def __init__( self, value, unit ):

《Python面向对象编程指南》——2.5 __bytes__()方法

2.5 __bytes__()方法 只有很少的情景需要我们把对象转换为字节.在第2部分"持久化和序列化"中,我们会详细探讨这个主题. 通常,应用程序会创建一个字符串,然后使用Python的IO类内置的编码方法将字符串转换为字节.对于大多数情况,这种方法就足够了.只有当我们自定义一种新的字符串时,我们会需要定义这个字符串的编码方法. 依据不同的参数,bytes()函数的行为也不同. bytes(integer):返回一个不可变的字节对象,这个对象包含了给定数量的0x00值. bytes(

《Python面向对象编程指南》——2.2 __format__()方法

2.2 __format__()方法 string.format()和内置的format()函数都使用了__format__()方法.它们都是为了获得给定对象的一个符合要求的字符串表示. 下面是给__format__()传参的两种方式. someobject.__format__(""):当应用程序中出现format(someobject)或者"{0}".format(someobject)时,会默认以这种方式调用__format__().在这些情况下,会传递一个空