代码改变世界

Python学习笔记《Python核心编程》第13章 面向对象编程

2013-01-28 20:05  VVG  阅读(4489)  评论(0编辑  收藏

类:

    类与函数的声明很相似,如下:

class ClassName(object):

      'class documentation string'      #类文档字符串

      class_suite                       #类体

类属性:         

 class c(object);

       foo = 100                #类属性,也就是静态属性,直接通过类名引用,不通过过实例

 print c.foo                    # 100

类方法:

 class MyClass(object):

        def myNoActionMethod(self):

            pass

 mc = MyClass()

 mc.myNoActionMethod()         #必须通过实例调用方法

特殊的类属性:

     对于任何类C,显示如下:

     C.__name__           类C的名字(string)

     C.__doc__             类C的文档字符串

     C.__bases__          类C的所有父类构成元素(包含了以个由所有父类组成的元组)

     C.__dict__             类C的属性(包含一个字典,由类的数据属性组成) 

     C.__module__        类C定义所在的模块(类C的全名是'__main__.C',如果C位于一个导入模块mymod中,那么C.__module__ 等于 mymod)

     C.__class__           实例C对应的类

实例:

     如果类是一种数据结构定义类型,那么实例则声明了以个这种类型的变量。实例是有生命的类。  通过调用类对象来创建实例。     

     __init__() “构造器”方法(相当于构造函数),在类调用实例化的时候检查是否有__init__方法,如果有就调用它。__init__应当返回None

     __new__() ....? 与楼上的有啥区别?

     __del__() "解构器"方法,该函数要直到该实例对象所有的引用都被清除掉后才会执行。解构器只能被调用一次,一旦引用计数为0,则对象就被清除了

实例属性:设置实例的属性可以再实例创建后任意时间进行;内建函数dir()可以显示类属性,也可以显示实例属性。

特殊的实例属性,任意对象I

I.__class__                      实例化I的类

I.__dict__                       I的属性,内建类型不存在__dict__属性,内建类型:int  float complex....

类属性与实例属性

      类属性通过 类名.属性名 来访问,也可以通过  实例名.属性名 来访问,但是类属性只能通过类来更新(不可变对象),如果给这个实例同一个属性赋值

这会在这个实例上面增加这个属性,不会影响类属性。

静态方法和类方法:

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

class TestStaticMethod:
    def foo():
        print 'calling static method foo()'        
    foo = staticmethod(foo)

class TestClassMethod:
    def foo(cls):
        print 'calling class method foo()'
        print 'foo() is part of class:',cls.__name__
    foo = classmethod(foo)

tsm = TestStaticMethod()
TestStaticMethod.foo()    # calling static method foo()
tsm.foo()                 #calling static method foo()

tcm = TestClassMethod()
TestClassMethod.foo()     #calling class method foo\n  foo() is part of class: TestClassMethod
tcm.foo()                 # 同上

使用函数修饰符:

     除了上面的使用内建方法外,还可以使用函数修饰符如下:

class TestStaticMethod:
    @staticmethod
    def foo():
        print 'calling static method foo()'        

class TestClassMethod:
    @classmethod
    def foo(cls):
        print 'calling class method foo()'
        print 'foo() is part of class:',cls.__name__

tsm = TestStaticMethod()
TestStaticMethod.foo()   # calling static method foo()
tsm.foo()    #calling static method foo()

tcm = TestClassMethod()
TestClassMethod.foo()     #calling class method foo\n  foo() is part of class: TestClassMethod
tcm.foo()    # 同上

子类和派生:

     创建子类: 括号里面是父类,如果没有从任何祖先类派生,可以使用object作为父类的名字。                

class SubClassName(ParentClass1[,ParentClass2,...]):

      'optional class documentation string'

      class_suite

__bases__类属性:对于任何子类,它是以个包含其父类的集合的元组。没有父类的类,他们的__bases__属性为空。

在子类方法中调用父类同名方法:

class P(object):    #父类

    def foo(self):

    print 'Hi, I am P-foo()'

class C(P):         #子类,继承父类P

    def foo(self):

    P.foo(self)     #调用父类同名方法

    print 'Hi, I am C-foo()' 

super()内建方法:super()不但能找到基类方法,而且还为我们传进self,如下:

class C(p):
    def foo(self):
        super(C,self).foo()   #调用C基类方法,自动查找C的基类
        print 'Hi,I am C-foo()'

从标准类型派生:

    a.不可变类型的例子:

class RoundFloat(float):
     def __new__(cls,val):  #覆盖float中的__new__
          return float.__new__(cls,round(val,2))  #  也可以 return super(RoundFloat,cls).__new__(cls,round(val,2))

    b. 可变类型的例子:

class SortedKeyDict(dict):
    def keys(self):
        return sorted(super(SortedKeyDict,self).keys())

c = SortedKeyDict({'zheng-cai':67,'hui-jun':68,'xin-yi':2})
>>> c.keys()
['hui-jun', 'xin-yi', 'zheng-cai']
>>> print [key for key in c]
['zheng-cai', 'xin-yi', 'hui-jun']

多重继承:

     python允许类继承多个基类,即多重继承。

     经典类继承使用深度优先,新式类采用广度优先查找属性,新式类有一个__mor__属性,显示继承的查找顺序。 

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

        issubclass(sub,sup): 判断一个类是另一个类的子类或者子孙类,如果是就返回True,第二个参数可以使可能父类组成的元组,只要第一个参数是其中给定元组中任何一个候选类的子类时,就返回True。

        isinstance(obj1,class1):判断一个对象是否是另一个给定类的实例.是就返回True。第二个参数应当是类。

        hasattr()\getattr()\setattr()\delattr() ------ 系列函数可以在各种对象下工作,不限于类和实例。操作obj.attr时就相当于调用*attr(obj,'attr')系列函数。 

class myClass(object):
    def __init__(self):
        self.foo = 100
        
 myInst = myClass()
 hasattr(myInst,'foo')
#True
 getattr(myInst,'foo')         #100
setattr(myInst,'bar',200)
getattr(myInst,'bar')          #200
delattr(myInst,'bar')
hasattr(myInst,'bar')         #False

dir(): 作用在实例上时,显示实例变量,还有实例所在的类及所有它的基类中定义的方法和类属性;作用在类上时,则显示类以及它的所有基类的__dict__中的内容。作用在模块上时,则显示模块的__dict__的内容。不带参数时,则显示调用者的局部变量。

super(type[,obj]) 函数:帮助找出相应的父类,然后方便调用相关的属性;super(MyClass,self).__init__()。

var()函数:与dir()类似。

类,实例及其他对象的内建函数

issubclass(sub,sup)     如果类sub是类sup的子类,则返回True,反之为False
isinstance(obj1,obj2)  如果实例obj1是类obj2或者obj2子类的一个实例;或者obj1是obj2的类型,则返回True;反之为Fasle
hasattr(obj,attr)    如果obj有属性attr(用字符串给出),返回True,反之,返回False
getattr(obj,attr[,default])   获取obj的attr属性;与返回obj.attr类似;如果attr不是obj的属性,如果提供了默认值,则返回默认值;不然就会引发一个异常 
setattr(obj,attr,val)  设置obj的attr属性值为val,替换任何已纯在的属性值;不然就创建属性;类似obj.attr = val
delattr(obj,attr)   从obj中删除属性attr,类似于del obj.attr
 dir(obj= None)    返回obj的属性的一个列表;如果没有给定obj,dir()则显示局部名字空间中的属性,也就是locals().keys()
 super(type,obj=None)  返回一个表示父类类型的代理对象;如果没有传入obj,则返回的super对象是非绑定的,反之,如果是以个type,issubclass(obj,type)必为True;否者isinstance(obj,type)就必为True
 vars(obj=None)     返回obj的属性及其值的一个字典;如果没有给出obj,vars()显示局部名字空间字典,也就是locals()