《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所有特性都是公开可用的。

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

接口和内省:略。

面向对象设计:略。

原文地址:https://www.cnblogs.com/dadada/p/3067653.html