Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6276474
  • 博文数量: 2759
  • 博客积分: 1021
  • 博客等级: 中士
  • 技术积分: 4091
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-11 14:14
文章分类

全部博文(2759)

文章存档

2019年(1)

2017年(84)

2016年(196)

2015年(204)

2014年(636)

2013年(1176)

2012年(463)

分类: Python/Ruby

2013-09-18 00:38:16

原文地址:Python之对象与面向对象 作者:scq2099yt

一、模块导入
        Python有两种导入模块的方法,import module和from module import,二者功能基本相同,但也有细微差别,举例说明如下:
        >>> import types
        >>> types.FunctionType                        (1)
       
        >>> FunctionType                                (2)
        Traceback (innermost last):
            File "", line 1, in ?
        NameError: There is no variable named 'FunctionType'
        >>> from types import FunctionType     (3)        
        >>> FunctionType                               (4)
       
        (1)types模块不包含方法,只是表示每种Python对象类型的属性,注意这个属性必须要用模块名types进行限定。
        (2)FunctionType本身没有被定义在当前名字空间中,它只存在于types的上下文环境中。
        (3)这个语法从types模块中直接将FunctionType属性导入到局部名字空间中。
        (4)现在FunctionType可以直接使用,与types无关了。
        从上不难看出,二者区别在于后者被导入模块types的属性和方法被直接导入到局部名字空间去了,所以它们可以直接使用,而不需要加上模块名的限定。那么什么时候使用from module import呢:
        (1)如果你要经常访问模块的属性和方法,且不想一遍又一遍地敲入模块名,使用from module import。
        (2)如果你想要有选择地导入某些属性和方法,而不想要其它的,使用from module import。
        (3)如果模块包含的属性和方法与你的某个模块同名,你必须使用import module来避免名字冲突。
        需要注意的是:应该尽量少用from module import *,因为判定一个特殊的函数或属性是从哪里来的有些困难,并且会造成调试和重构都更困难。
        更多关于二者的区别,请参看。            

二、类的定义
        Python是完全面向对象的,你可以定义自己的类,从自己的或者内置的类继承,然后从你定义的类创建实例。
1、简单类或基类
        在Python中定义类很简单,Python类以保留字class开始,后面跟着类名:
        class Loaf:        (1)
            pass            (2)(3)
        (1)类名通常第一个字母大写,但这不是必须的。
        (2)类可以没有任何方法或属性,但从语法上,需要在定义中有些东西,所以需要一个占位符pass,它是Python的保留字,其什么都不做仅仅表示“向前看,不要往这里看”。pass语句类似于C/C++中的大括号空集{}。
        (3)在类中所有东西都要缩进,第一条不缩进的语句不属于这个类。
2、继承类或子类
        from UserDict import UserDict
        class FileInfo(UserDict):        
        在Python中,类的基类只是简单地列在类名后面的小括号里,所以FileInfo类是从UserDict类继承而来的。Python支持多重继承,在类名后面的小括号中,列出所有基类,以逗号分隔。
        Python类没有显示的构造函数和析构函数,但有类似构造函数的方法__init__。
        class FileInfo(UserDict)
                "store file metadata"                           (1)
                def __init__(self, filename=None):        (2)
                        UserDict.__init__(self)                 (3)
                        self["name"] = filename             
        (1)类可以并且应该有doc strings,就像方法和函数一样。
        (2)__init__在类的实例创建后被立即调用,其行为与C++中的构造函数相似,但区别是Python中对象在调用__init__时已经被构造出来了,且已经有一个对类的新实例的有效引用。每个类方法的第一个参数,包括__init__,都是指向类的当前实例的引用,按照习惯为self,但不是必须如此命名,self类似于C++中的this,在__init__方法中,self指向新创建的对象,在其它类方法中,self指向方法被调用的类实例,在方法定义时需要明确指定self,但在调用方法时,不用指定self,Python会自动替你加上。__init__方法可以接受任意个数的参数,参数可以用缺省值定义,可以设置成对于调用者可选,比如:filename的缺省值为None,即Python的空值。__init__方法从不返回一个值。
        (3)Python中,父类的方法不会在子类方法执行前被自动调用,而必须显示地调用父类中的适合方法。
3、何时使用self和__init__
        (1)当定义你自己的类方法时,必须明确将self作为每个方法的第一个参数列出,包括__init__。
        (2)当从你的类中调用一个父类的一个方法时,必须包括self参数,但是当你从类的外部调用类的方法时,不必对self参数指定任何值,Python会自动地替你增加实例的引用即self。
        (3)__init__方法是可选的,但是一旦定义了,就必须记得显示调用父类的__init__方法(如果它定义了)。引申行为:无论何时子类想扩展父类的行为,子类方法必须在适当的时机,使用适当的参数,显示调用父类方法。
       
三、类的实例化
1、实例化
        在Python中对类进行实例化很直接,为了对类进行实例化,只要调用类,就像类是一个函数一样,传入定义在__init__方法中的参数,返回值将是新创建的对象:
        >>> import fileinfo
        >>> f = fileinfo.FileInfo("/music/_singles/kairo.mp3")    (1)
        >>> f.__class__                                                      (2)
       
        >>> f.__doc__                                                       (3)
        'store file metadata'
        >>> f                                                                    
        {'name': '/music/_singles/kairo.mp3'}
        (1)创建类FileInfo(定义在fileinfo模块中)的实例,将新创建的实例赋值给变量f,传入参数/music/_singles/kairo.mp3给__init__方法中的filename参数。
        (2)每个类的实例有一个内置属性,__class__是对象的类,类元数据可以通过对象本身的属性得到,包括__class__、__name__、__bases__等。
        (3)可以像对象函数或模块一样来访问实例的doc string,一个类的所有实例共享相同的doc string。
2、垃圾回收
        类实例的销毁非常简单,通常不需要明确地释放实例,当指派给实例的变量超出作用域时,会被自动地释放,内存泄露在Python中很少见,在Python中使用引用计数来实现垃圾回收。

四、类属性
        在Python中,类属性由类本身所拥有,数据属性由一个特定的类实例所拥有,类属性相当于C++中类的静态变量,数据属性相当于C++中类的成员变量,类属性定义在类定义之后,数据属性定义在__init__方法中。
1、类属性
        class MP3FileInfo(FileInfo):
                "store ID3V1.0 MP3 tags"
                tagDataMap = {"title"    :    (3, 33, stripnulls),
                                      "year"   :    (93, 97, stripnulls),
                                      "genre" :    (127, 128, ord)}
        >>> import fileinfo
        >>> fileinfo.MP3FileInfo                            (1)
       
        >>> fileinfo.MP3FileInfo.tagDataMap           (2)
        {'title' : (3, 33, ),
        'genre': (127, 128, ),
        'year' : (93, 97, )}
        >>> m = fileinfo.MP3FileInfo()                   (3)
        >>> m.tagDataMap
        {'title' : (3, 33, >),
        'genre': (127, 128, >),
        'year' : (93, 97, >)}
        (1)MP3FileInfo是类本身,不是任何类的特别实例。
        (2)tagDataMap是一个类属性,其在创建任何类实例之前就有效了。
        (3)类属性既可以通过直接对类的引用,也可以通过对类
的任意实例的引用来使用。
        类属性可以作为类级别的常量来使用,但是类属性不是真正的常量,你可以修改它:
        >>> class counter:
                        count = 0                                     (1)
                        def __init__(self):
                                self.__class__.count += 1        (2)
        >>> counter
       
        >>> counter.count                                        (3)
        0
        >>> c = counter()
        >>> c.count                                                  (4)
        1
        >>> counter.count
        1
        >>> d = counter()                                         (5)
        >>> d.count
        2
        >>> c.count
        2
        >>> counter.count
        2
        (1)count是counter类的一个类属性。
        (2)__class__是每个类实例的一个内置属性(也是每个类的),其是一个类的引用,而self是一个类的实例。
        (3)因为count是一个类属性,它可以在我们创建任何类实例之前,通过直接对类引用而得到。
        (4)创建一个类实例会调用__init__方法,它会给类属性count加1,这样会影响到类自身,不只是新创建的实例。
        (5)创建第二个实例将再次增加类属性count,注意类属性是如何被类和所有类实例所共享的。
2、数据属性
        class CType(object):
            a = 1                             (1)
        class DType(object):
            def __init__(self):        
                self.a = 1                    (2)
        (1)在类CType中,a就是类本身的属性,即类属性或静态变量。
        (2)在类DType中,a就是类实例的属性,即数据属性或成员变量。

五、私有函数
        与大多数语言一样,Python也有私有的概念:
        (1)私有函数不可以从它们的模块外面被调用;
        (2)私有类方法不能够从它们的类外面被调用;
        (3)私有属性不能够从它们的类外面被访问。
        与大多数语言不同,一个Python函数、方法或属性是私有还是公有,完全取决于它的名字。
        如果一个Python函数、类方法或属性的名字以两个下划线开始(但不是结束),它是私有的(只能在自己的类中使用),其它所有的都是公有的(任何地方都可使用)。Python没有类方法保护的概念。如果试图调用一个私有方法,Python将会引发一个有误导的异常,宣称该方法不存在。



阅读(584) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~