一、面向对象高级编程
- 使用__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'