python学习笔记之类

2013年05月26日 分类:学习笔记Python

和其他面向对象的编程语言一样,python也是可以定义类的,下面我将对python中的类做一下总结,主要包括:类的定义、继承、静态方法、类方法、特性和运算符重载。

1.类的定义

和c++一样,Python使用关键字class定义类。

class People(object):
 numbers = 0
 def __init__(self, name, age, male, address):
 	self.name = name
 	self.age = age
 	self.male = male
 	self.address = address
 	People.numbers += 1
 def __del__(self):
 	People.numbers -= 1
 def eat(self, food):
 	print self.name + ' is eating ' + food + '.'
>>> wuyuan = People('wuyuan', 20, True, 'wuyuans.com')
>>> wuyuan.eat('apple')
wuyuan is eating apple.
>>> wuyuan.name
'wuyuan'

类通常由类变量、方法和属性组成,其中类变量相当于c++中类的静态变量,所有该类的实例都可以访问,通常用于保存公共资源和类实例的相关信息,比如实例的数量。Python中类的方法和一般的有点不一样,多了个self,这个相当于c#中的this变量,表示当前对象实例,在类中访问实例方法和属性时都需要使用self来指示。属性就是类的实例变量,也可以说是成员变量,一般在构造函数init中定义,del为类的析构函数。

2.类的继承

在class语句中可以使用以逗号分隔的基类列表来指定继承,如果未指明将默认继承object类。

class Student(People):
 def __init__(self, name, age, male, address, school):
 	self.school = school
 	super(Student, self).__init__(name, age, male, address)	
 def eat(self, food):
 	print 'Student ' + self.name + ' is eating ' + food + '.'
>>> wuyuan.eat('apple')
Student wuyuan is eating apple.

子类可以重定义父类的方法,比如构造函数init,以此来添加子类成员变量。使用super函数也可以在构造函数中调用父类的init,或者直接使用People.init()调用。在使用super时父类在定义时必须继承object类,否则出现TypeError: TypeError: must be type, not classobj

3.静态方法和类方法

Python中类的方法一般以实例作为第一个参数self传递,但也有例外的情况,比如静态方法和类方法。

3.1.静态方法

和其他面向对象语言一样,Python的类中也可以定义静态方法,使用@staticmenthod装饰器定义。因为没有传递self参数,静态方法不会对任何实例类型进行操作。

class Foo(object):
 @staticmethod
 def add(x, y):
 	return x + y
>>> Foo.add(1, 2)
3

如果在编写类时需要采用不同的方式创建新实例,比如工厂模式,则通常使用静态方法。

3.2.类方法

类方法和静态方法很相似,不同的是当前类将作为第一个参数cls传递,使用@classmethod装饰器定义。

class Times(object):
 factor = 1
 @classmethod
 def mul(cls, x):
 	return cls.factor * x

class TwoTimes(Times):
 factor = 2

>>> Times.mul(3)
3
>>> TwoTimes.mul(3)
6

TwoTimes是Times的子类,但在调用mul时cls为TwoTimes,所以cls.factor为2。

4.特性

特性是一种特殊的属性,访问它时会计算他的值,和c#中的属性类似,使用@property装饰器定义。

class Circle(object):
 def __init__(self, r):
 	self.__radius = r
 @property
 def area(self):
 	return math.pi * self.__radius ** 2
 @property
 def perimeter(self):
 	return 2 * math.pi * self.__radius
 	
 @property
 def radius(self):
 	return self.__radius
 @radius.setter
 def radius(self, value):
 	if not isinstance(value, float):
   raise TypeError('Must be a float')
 	self.__radius = value
 @radius.deleter
 def radius(self):
 	self.__radius = 0
 	
>>> c = Circle(3.0)
>>> c.radius
3.0
>>> c.area
28.274333882308138
>>> c.perimeter
18.84955592153876
# 赋值
>>> c.radius = 4.0
>>> c.radius
4.0
# 删除
>>> del c.radius
>>> c.radius
0

当定义了特性后,只能简单访问该特性,要做赋值和删除操作的话必须附加setter和deleter方法。

5.运算符重载

和c++一样,Python也可以对运算符进行重载。可以重载的方法如下表所示。
MethodOverloadsCall for
init构造函数X=Class()
del析构函数对象销毁
repr打印转换 print X,repr(X)
str打印转换 print X,str(X)
call调用函数X()
getattr 限制X.undefine
setattr取值X.any=value
getitem索引 X[key],For If
setitem索引 X[key]=value
len长度len(X)
iter迭代

For In

add + X+Y,X+=Y
sub-X-Y,X-=Y
mul*X*Y
radd右加+ +X
iadd+=X+=Y
or|X|Y,X|=Y
cmp比较 ==X==Y,X
lt小于<X
eq等于=X=Y

class Number(object):
 def __init__(self, value):
 	self.value = value
 # 加重载
 def __add__(self, other):
 	return Number(self.value + other.value)
 # 打印重载
 def __str__(self):
 	return 'The value is %d.' % self.value
 # 比较重载
 def __cmp__(self, other):
 	return cmp(self.value, other.value)
 	
>>> x = Number(1)
>>> y = Number(2)
>>> print x + y
The value is 3.
>>> x > y
False
>>> x < y
True
作者:wuyuan 本文来自Wuyuan's Blog 转载请注明,谢谢! 文章地址: https://wuyuans.com/2013/05/python-class