类和类型

旧版本Python中,类和类型之间有明显区别:內建的对象是基于类型的,自定义的对象则是基于类的,可以创建类但不能创建类型。最近版本的Python中,可以创建内建类型的子类(或子类型),这些类型的行为也更类似于类。


1.创建类

__metaclass__ = type     # 确定使用新式类
class Person:            # class语句会在函数定义的地方创建自己的命名空间
    def setName(self, name):
        self.name = name
    def getName(self):
        return self.name
    def greeting(self):  # 对象.greet() 等同于 类.greet(对象)
        print "Hello, world! I'm %s." % self.name

除非是Python 3.0之前版本中默认附带的代码,否则再继续使用旧式类已无必要。新式类需要在模块或脚本开始时放置赋值语句__metaclass__ = type,除此之外还可通过继承新式类(如Object)来实现。

2.特性、函数和方法

self参数是方法和参数的区别,方法将其第一个参数绑定到所属的实例上,因此无需显式提供该参数(不需要self参数时也可以将特性绑定到普通函数上);

>>> class Class:
        def method(self):
            print 'I have a self!'
>>> def function():
        print "I don't..."
>>> instance = Class()
>>> instance.method()
I have a self!
>>> instance.method = function
>>> instance.mathod()
I don't...

self参数并不依赖于调用方法的方式,可以随意使用其他变量引用同一个方法;

class Bird:
    song = 'Squaawk!'
    def sing(self):
        print self.song
>>> bird = Bird()
>>> birdsong = bird.sing
>>> birdsong()
Squaawk!

只要在其名字前面加上双下划线就可以使方法或特性变成私有(从外部无法访问),类的内部定义中,所有以双下划线开始的名字都被“翻译”成前面加上单下划线和类名的形式。

class Secretive:
    def __inacessible(self):
        print "Bet you can't see me..."
    def acessible(self):
        print "The srcret message is:"
        self.__inacessible()
>>> s = Secretive()
>>> s._Secretive__inacessible()
Bet you can't see me...

若要让其他对象不要访问内部数据,可以使用单下划线,前面有下划线的名字不会被带星号的import语句(form module import *)导入。

3.类的命名空间

所有位于class语句内的代码都在特殊的命名空间中执行——类命名空间,该命名空间可由类内所有成员访问。

class MemberCounter:
    mombers = 0
    def init(self):
        Membercounter.mombers += 1
>>> m1 = MemberCounter()
>>> m1.init()
>>> MemberCounter.members
1
>>> m2 = MemberCounter()
>>> m2.init()
>>> MemberCounter.members
2

4.指定超类

将其他类名卸载class语句后的括号内可以指定超类,子类可以扩展超类的定义:

class Filter:
    def init(self):
        self.blocked = []
    def filter(self, sequence):
        return [x for x in sequence if x not in self.blocked]
class SPAMFilter(Filter):       # SPAMFilter是Filter的子类
    def init(self):             # 重写Filter超类中的init方法
        self.blocked = ['SPAM']

5.检查继承

  • 内建的issubclass(子类, 超类)函数可以查看一个类是否是另一个的子类;
  • 使用特殊特性__bases__可以查看已知类的基类;
  • instance(对象, 类)可以检查一个对象是否是一个类的实例;
  • __class__特性可以查看对象所属的类;
>>> SPAMFilter.__bases__
(<class __main.Filter at 0x171e40>)
>>> Filter.__bases__
()
>>> s.__class__
<class __main.SPAMFilter at 0x1707c0>

6.多个超类

若一个方法从多个超类中继承,先继承的类中的方法会重写后继承的类中的方法

7.接口与内省

results matching ""

    No results matching ""