[Python]面向对象编程(一)

来源:互联网 发布:淘宝开店上传坐套教程 编辑:程序博客网 时间:2024/05/21 22:28

     Python中的OOP相关术语:抽象/实现,封装/接口,合成,派生/继承/继承结构,泛化/特化,多态,自省/反射。

类的声明:

class ClassName(Bases):    'class documentation string'    class_suite
创建实例:

obj = ClassName()
类的数据属性

class C(object):    foo = 100print C.foo #100C.foo = C.foo + 1print C.foo #101
Methods
class MyClass(object):    def myNoActionMethod(self):        passmc = MyClass()mc.myNoActionMethod()
绑定(绑定及非绑定方法)

        为了与OOP管理保持一致,Python严格要求,没有实例,方法是不能被调用的。这种限制即Python所描述的绑定概念(binding),在此,方法必须绑定(到一个实例)才能直接被调用。非绑定的方法可能可以被调用,但实例对象一定要明确给出,才能确保调用成功。

决定类的属性

        要知道一个类有哪些属性,有两种方法。最简单的是使用dir()内建函数。另外是通过访问类的字典属性__dict__,这是所有类都具备的特殊属性之一。例:

class MyClass(object):    'MyClass class definition'    myVersion = 1.1    def showMyVersion(self):        print MyClass.myVersion        print dir(MyClass)print MyClass.__dict__

特殊的类属性

C.__name__     类C的名字(字符串) 

C.__doc__        类C的文档字符串

C.__bases__    类C的所有父类构成的元组

C.__dict__        类C的属性

C.__module__  类C定义所在的模块

C.__class__      实例C对应的类(仅在新式类中)

实例

(1)初始化

(2)__init__“构造器”方法

        当类被调用,实例化的第一步是创建实例对象。一旦对象创建了,Python检查是否实现了__init__()方法。默认情况下,如果没有定义(或覆盖)特殊方法__init__(),对实例不会施加任何特别的操作。任何所需的特定操作,都需要程序员实现__init__(),覆盖它的默认行为。如果__init__()没有实现,则返回它的对象,实例化过程完毕。

        然而,如果__init__()已经被实现,那么它将被调用,实例对象作为第一个参数(self)被传递进去,像标准方法调用一样。调用类时,传进的任何参数都交给了__init__()。实际中,你可以想像成这样:把创建实例的调用当成是对构造器的调用。

        总之,(a)你没有通过调用new 来创建实例,你也没有定义一个构造器。是Python 为你创建了对象; (b) __init__(),是在解释器为你创建一个实例后调用的第一个方法,在你开始使用它之前,这一步可以让你做些准备工作。

(3)__new__()“构造器”方法

        与__init__()相比,__new__()方法更像一个真正的构造器。类型和类在版本2.2 就统一了,Python 用户可以对内建类型进行派生,因此,需要一种途径来实例化不可变对象,比如,派生字符串,数字,等等。

在这种情况下,解释器则调用类的__new__()方法,一个静态方法,并且传入的参数是在类实例化操作时生成的。__new__()会调用父类的__new__()来创建对象(向上代理)。

(4)__del__()“解构器”方法

一些注意点:

不要忘记首先调用父类的__del__()。

调用 del x 不表示调用了x.__del__() -----前面也看到,它仅仅是减少x 的引用计数。

如果你有一个循环引用或其它的原因,让一个实例的引用逗留不去,该对象的__del__()可能永远不会被执行。

__del__()未捕获的异常会被忽略掉(因为一些在__del__()用到的变量或许已经被删除了)。不要在__del__()中干与实例没任何关系的事情。

除非你知道你正在干什么,否则不要去实现__del__()。

如果你定义了__del__,并且实例是某个循环的一部分,垃圾回收器将不会终止这个循环——你需要自已显式调用del。

静态方法和类方法

(1)staticmethod()和classmethod()内建函数

class TestStaticMethod:    def foo():        print "calling static method"    foo = staticmethod(foo)    class  TestClassMethod:    def bar(cls):        print "calling class method"    bar = classmethod(bar)
(2)使用函数修饰符

class TestStaticMethod:    @staticmethod    def foo():        print "calling static method"        class  TestClassMethod:    @classmethod    def bar(cls):        print "calling class method"

子类和派生

    创建子类:

class SubClassName(ParentClass1[,ParentClass2,...]):    'optional class documentation string'    class_suite
通过继承覆盖方法

class P(object):    def foo(self):        print "Hi,I am P-foo()"class C(P):    def foo(self):        super(C,self).foo()        print "Hi,I am C-foo()"    p = P()c = C()p.foo() c.foo()
注意:重写__init__不会自动调用基类的__init__。

从标准类派生

class RoundFloat(float):    def __new__(cls,val):        return super(RoundFloat,cls).__new__(cls,round(val,2))    print RoundFloat(1.5955)print RoundFloat(1.5945)print RoundFloat(-1.9955)
1.6
1.59
-2.0

class SortedDict(dict):    def keys(self):        return sorted(super(SortedDict,self).keys())d = SortedDict(zip(["hui","difalo","xxik"],[89,87,56]))print "By iterator:".ljust(12),[keys for keys in d]print "By keys():".ljust(12),d.keys()
By iterator: ['xxik', 'hui', 'difalo']
By keys():   ['difalo', 'hui', 'xxik']

多重继承

    经典类MRO(Method Resolution Order)为深度优先(DF),新式类为广度优先(BF)。

类、实例和其他对象的内建函数

    issubclass(),isinstance()

    hasattr(),getattr(),setattr(),delattr()

    dir()

    super()

    vars()

私有化

(1)双下划线

        不允许对象直接访问,可以看做模块导入的保护机制,保护__xxx不与父类名字空间相冲突。

(2)单下划线

        简单的模块私有化只需要在属性名前,使用一个单下划线字符,就能防止模块的属性用"from module import *"来加载。

REF:Python核心编程



0 0