zoukankan      html  css  js  c++  java
  • 《Python基础教程》要点(七):更加抽象:类

    概要:

    一、创建类

    二、特性、函数和方法

    三、类的命名空间

    四、指定超类

    五、调查继承

    六、多个超类

    七、接口和内省

    一、创建类:

     1 >>> __metaclass__ = type #确定使用新式类
     2 >>> class Person:
     3 
     4     def setName(self,name):
     5         self.name = name
     6     def getName(self,name):
     7         return self.name
     8     def greet(self):
     9         print"Hello  world ! I'm %s." % self.name      

    self参数是对于对象自身的引用。

    【注意】新式类的语法中,需要在模块或者脚本开始的地方放置赋值语句__metaclass__ = type。此外,也可以继承新式类(比如object)。

    创建实例看看:

    1 >>> tom = Person()
    2 >>> john = Person()
    3 >>> tom.setName('Tom')
    4 >>> john.setName('John')
    5 >>> tom.greet()
    6 Hello  world ! I'm Tom.
    7 >>> john.greet()
    8 Hello  world ! I'm John.

    【提示】tom 是 Person 的实例的话,那么还可以把 tom.greet() 看做 Person.greet(tom)方便的简写。

    二、特性、函数和方法

    self 参数事实上正是方法函数的区别。

    方法:(更专业一点可以称为绑定方法)将它们的第一个参数绑定到所属的实例上,因此这个参数可以不必提供。

    可以将特性绑定到一个普通函数上,这样就不会有特色的self参数了:

     1 >>> class myclass:
     2     def mymethod(self):       #这个是类的 方法
     3         print' method() from a class must take arguments (1 given)!!'
     4 
     5         
     6 >>> instance = myclass()
     7 >>> instance.mymethod()
     8  mymethod() must take arguments (1 given)!!
     9 >>> 
    10 >>> def function():          #这个是普通函数
    11     print 'now NOT belong to a class and no self argument'
    12 
    13     
    14 >>> f = function()
    15 now NOT belong to a class and no self argument

    注意:self参数并不取决于调用方法的方式,可以如上的实例调用,也可以随意使用引用同一个方法的其他变量

    1 >>> instance = myclass()
    2 >>> instance.mymethod() #实例调用
    3  mymethod() must take arguments (1 given)!!
    
    4
    >>> mymd = instance.mymethod #也可以随意使用引用同一个方法的其他变量 5 >>> mymd() 6 mymethod() must take arguments (1 given)!!

    上面的第二个方法调用,变量mymd 引用instance.mymethod这个绑定方法,也就意味着这还是对self参数的访问(也就是还是那个 instance,它仍旧绑定到类的相同实例上)。

    程序可以从外部访问一个对象的特性

    私有特性,外部对象无法访问,但getName和setName等访问器(accessor)能够访问。

    Python并不直接支持私有方式。

    让方法或者属性变为私有(从外部无法访问),只要在它的名字前面加上双划线即可:

    >>> class Person:
        def __say(self):
            print'I love you.'
        def accessiable(self):
            print'what he want to say is :'
            self.__say()
    
            
    >>> tom = Person()
    >>> tom.accessiable()
    what he want to say is :
    I love you.

    类的内部定义中,所有以双划线开始的名字都被“翻译”成前面加上单下划线和类名的形式:

    >>> Person._Person__say
    <unbound method Person.__say>

    实际上还是能在类外访问这些私有方法,尽管不应该这么做:

    >>> tom._Person__say()
    I love you.

    哈哈,不过是个“名称变化术”!

    Python并没有真正的私有化支持。

    如果不需要使用这种方法,但又想让其他对象不要访问内部数据,可以使用单下划线。

    这不过是个习惯,但有效哦。例如,前面有下划线的名字都不会被带星号的imports语句(from module import *)导入。

    三、类的命名空间

     定义类时,所有位于class语句中的代码都在特殊的命名空间中执行--类命名空间(class namespace)。这个命名空间可由类内所有成员访问。

    通俗点:比如一个类里面定义了一个变量(像java里的成员变量),或者方法,它就可以被所有实例访问。

    重绑定后的特性值会屏蔽掉类范围类的变量值,但是其他没有重绑定该特性的实例不受影响。

    类的定义其实就是执行代码块。

    四、指定超类

    超类:其实就像C++里的父类。

    指定超类的方法:将其他类名写在class语句后的圆括号内。这样子类可以扩展超类的定义啦!

    122页有关过滤类的代码可以看看。

     1 >>> class Father:
     2     def init(self):
     3         print'This is Father class.'
     4 
     5         
     6 >>> class Son(Father):
     7     def say(self):
     8         print'This is son speaking'
     9 
    10         
    11 >>> tom = Son()
    12 >>> tom.init()
    13 This is Father class.
    14 >>> tom.say()
    15 This is son speaking

    五、调查继承

    查看一个类是否是另一个类的子类,可以使用内建的issubclass函数

    >>> issubclass(Son,Father)
    True

    查看已知类的基类(们),可以直接使用它的特殊特性__bases__:

    >>> Son.__bases__
    (<class __main__.Father at 0x01617260>,)
    
    >>> Father.__bases__
    ()

    检查一个对象是否是一个类的实例,使用 isinstance函数

    >>> isinstance(tom,Son)
    True
    
    >>> isinstance('d',str)
    True

    检查一个对象属于哪个类,可以使用__class__特性

    >>> tom.__class__
    <class __main__.Son at 0x01C89DF8>

    【注意】如果使用__metaclass__ = type 或者从object继承的方式来定义新式类,那么可以使用type(tom)查看实例的类。

    六、多个超类

    子类自己可以不做任何事,从自己的超类继承所有行为:

    >>> class Father:
        def init(self):
            print'This is Father class.'
    
            
    >>> class Mother:
        def sing(self):
            print'I can sing a song !'
    
            
    >>> class Girl(Father,Mother):
        pass
    
    >>> juni = Girl()
    >>> juni.init()
    This is Father class.
    >>> juni.sing()
    I can sing a song !

    这也称为多重继承,除非特别熟悉,否则避免使用。

    先继承的类中的方法,会重写后继承的类中、具有相同名字的不同方法。

    七、接口和内省

    检查所需方法是否已经存在

    >>> hasattr(juni,'run')
    False
    >>> hasattr(juni,'sing')
    True

    【注意】callable函数在Python3.0不再用,可以使用hasattr(x,'__call__')代替。

    检查特性(方法吧)是否可调用:

    >>> callable(getattr(juni,'sing',None))
    True
    >>> callable(getattr(juni,'run',None))
    False

    这里使用 getattr 函数 ,该函数允许提供默认值(本例中为None),以便在特性不存在时使用。那就无需if 一下hasattr()一下判断了,直接getattr啦!

    与getattr 相对应的函数是setattr,可以用来设置对象的特性

    >>> setattr(juni,'name','Juniffer')
    >>> juni.name
    'Juniffer'

    小结

    对象:包括特性和方法。

    :每个对象都有一个类。类的主要任务是定义它的实例会用到的方法。

    多态:对不同类型和类的对象进行同样对待的特性--不需要知道对象属于哪个类就能调用方法。(区别java反射机制里是如何调用一个对象的方法的)

    封装:对象可以将它们内部状态隐藏(或封装)起来。虽然Python所有特性都是公开可用的。

    继承:一个类可以是一个或多个类的子类。

    接口和内省:略。

    面向对象设计:略。

  • 相关阅读:
    P1032 字串变换
    P3203 [HNOI2010]弹飞绵羊
    P3690 【模板】Link Cut Tree (动态树)
    P2147 [SDOI2008]洞穴勘测
    P3950 部落冲突
    Codeforces Round #469 Div. 2题解
    线段树
    SDOI2018退役记
    4.1模拟题
    无旋Treap
  • 原文地址:https://www.cnblogs.com/dadada/p/3067653.html
Copyright © 2011-2022 走看看