一、面向对象高级编程

  1. 使用__slots__

__slots__是一个特殊的变量,用来限制该class实例能动态添加的属性。__slots__中定义的属性只能对当前类起作用,对继承的子类是不起作用的。除非在子类中也定义___slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。

>>> class Student(object):
...     __slots__=('name','gender')
...
>>> s=Student()
>>> s.name='zw'
>>> s.age=20
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'age'

由于age没有被放到__slots__中,所以不能绑定age属性,视图绑定age属性会得到AttributeError错误。 

     2.使用@property

作用:Python内置的@property装饰器就是负责把一个方法变成属性来调用

用法:把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值。

举例:

class Student(object):

    @property
    def birth(self):
        return self._birth

    @birth.setter
    def birth(self, value):
        self._birth = value
    #只定义getter方法,不定义setter方法就是一个只读属性:
    @property
    def age(self):
        return 2015 - self._birth

s=Student()
s.birth=1999
print(s.age)

    3.多重继承

定义:一个子类继承多个父类,通过多重继承,一个子类就可以同时获得多个父类的所有功能。

class Animal(object):
    pass

class Runnable(object):
    pass

class Dog(Animal,Runnable):
    pass

Dog类同时继承了Animal类和Runnable类,获得这两个类的所有功能。 

    4.定制类

  • __str__

用来打印实例

>>> class Student(object):
...     def __init__(self,name):
...             self.name=name
...     def __str__(self):
...             return 'Student object (name: %s)' % self.name
...
>>> print(Student('zw'))
Student object (name: zw)
  • __iter__

如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象。然后,Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。

class Fib(object):
    def __init__(self):
        self.a,self.b=0,1
    def __iter__(self):
        return self  #实例本身就是迭代对象,所以返回自己
    def __next__(self):
        self.a,self.b=self.b,self.a+self.b
        if self.a>10:  #循环终止条件
            raise StopIteration()
        return self.a  #返回下一个值

for n in Fib():
    print(n)

输出

1
1
2
3
5
8
  •  __getitem__

要表现得像list那样按照下标取出元素,需要实现__getitem__()方法:

class Fib(object):
    def __getitem__(self,n):
        a,b=1,1
        for x in range(n):
            a,b=b,a+b
        return a

f=Fib()
for i in range(0,5):
    print(f[i])
  • __getattr__

当调用不存在的属性时,会抛出AttributeError错误,写一个__getattr__()方法,当调用不存在的属性时,动态返回一个属性,避免这个错误。

class Student(object):
    def __init__(self):
        self.name='zw'

    def __getattr__(self,attr):
        if attr=='score':
            return 100
    
s=Student()
print(s.name)
print(s.score)

也可以用来返回函数

class Student(object):

    def __getattr__(self,attr):
        if attr=='score':
            return lambda:25

s=Student()
print(s.score())
  • __call__

__call__方法是用来提供直接在实例身上调用方法而不是通过instance.method()调用。

class Student(object):

    def __init__(self,name):
        self.name=name
    def __call__(self):
        print('My name is %s' % self.name)

s=Student('zw')
s()

用callable判断一个对象能否被调用

print(callable(s))
print(callable([1,2]))
True
False

  5.枚举类

为枚举类型定义一个class类型,然后,每个常量都是class的一个唯一实例。

from enum import Enum

Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

   6.使用元类

  • type()

使用type()动态创建类

  • metaclass

定义:metaclass用来创建类,先定义metaclass,然后创建类。

用法:先定义metaclass,就可以创建类,最后创建实例。

 二、IO编程

  1.文件读写

读写文件之前首先要用Python内置的open()函数打开这个文件,传入文件名和标识符,标识符r表示只读方式打开文件,标识符w表示以写入文件方式打开文件

>>> f=open('zw.txt','r')
>>> f.read()

用close()方法关闭文件

  2.操作文件和目录

Python的os模块封装了操作系统的目录和文件操作,要注意这些函数有的在os模块中,有的在os.path模块中。

用os查看当前的绝对路径

>>> import os
>>> os.path.abspath('.')
'C:\\Users\\Administrator'