类的定义

类的定义

类的基本定义格式:

1
2
3
class ClassName:
'类的帮助信息' #类文档字符串
class_suite #类体

代码实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class Employee:
'所有员工的基类'
empCount = 0

def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1

def displayCount(self):
print "Total Employee %d" % Employee.empCount

def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary

  • 需要注意的是上面Employee类里面的empCount变量,这个变量在该类的所有实例里面共享,和C++里面的static成员变量类似。在赋值的时候我们看到用的是Employee.empCount的方式,而不是self.empCount的方式。在python的类中,同一个类的不同对象可能会拥有不同的变量,在类中直接使用self.value就可以定义类的变量,在创建了对象后,也可以使用Object.value创建对象的变量和为对象的变量赋值。

  • self代表类的实例,self在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。self代表的是实例,而不是对象。另外self并不是Python的关键字,将self换成其它变量字符串也是可以的。

类的属性与方法,private,protected,pubilc

类的方法
在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数。

类的私有方法或变量
private:两个下划线开头,声明该方法为私有方法或变量,不能在类的外部调用额访问。在类的内部调用 self.private。

类的protected类型变量或方法
_foo: 以单下划线开头的表示的是 protected 类型的变量或方法,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *。

类的public类型变量或方法
前面没有下滑线的方法或者变量,允许外部访问和调用。

需要说明的是头尾双下滑线定义的是特殊方法,一般是系统定义名字,类似init( )之类的。

构造函数、析构函数

构造函数:__init__( )

  • __init__( )方法是类的构造函数名字,创建这个类的实例的时候会调用该方法。注意该函数没有返回值。

析构函数: __del__( )

  • 析构函数 deldel在对象销毁的时候被调用,当对象不再被使用时,del方法运行.需要注意的是Pyhton使用引用计数的方法来管理垃圾回收,也就是当我们使用del Object的时候,该对象可能并没有被释放,因为引用计数还不是0,当引用计数为0的时候才会调用del方法。

类的继承

有父类(类的继承):

1
2
class 派生类名(基类名)
...

继承多个类:

1
2
3
4
5
6
7
class A:        # 定义类 A
.....

class B: # 定义类 B
.....

class C(A, B): # 继承类 A 和 B

  • 1、如果在子类中需要父类的构造方法就需要显示的调用父类的构造方法,或者不重写父类的构造方法。

  • 2、在调用基类的方法时,需要加上基类的类名前缀,且需要带上 self 参数变量。区别在于类中调用普通函数时并不需要带上 self 参数

  • 3、Python 总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。

Magic Methods

所谓的Magic Methods,也就是这些函数的调用不是用户直接调用的,而是在类的某个操作的时候被间接调用,比如实现add()方法,那么对对象进行+操作的时候就会调用该函数。
有一些基础的方法可能需要我们重写:

序号 方法, 描述 & 简单的调用
1 __init__ ( self [,args…] )
构造函数
简单的调用方法: obj = className(args)
2 __del__( self )
析构方法, 删除一个对象
简单的调用方法 : del obj
3 __repr__( self )
转化为供解释器读取的形式
简单的调用方法 : repr(obj)
4 __str__( self )
用于将值转化为适于人阅读的形式
简单的调用方法 : str(obj)
5 __cmp__ ( self, x )
对象比较
简单的调用方法 : cmp(obj, x)

代码例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/python
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b

def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)

def __add__(self,other):
return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2,10)
v2 = Vector(5,-2)
print v1 + v2

执行结果如下

1
Vector(7,8)

类和对象关系检测方法

  • issubclass() - 布尔函数判断一个类是另一个类的子类或者子孙类,语法:issubclass(sub,sup)

  • isinstance(obj, Class) 布尔函数如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true。

类的使用

创建实例对象

1
2
3
4
"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)

通过以上方式会调用Employee的__init__( )方法创建一个对象。

访问属性

访问对象的属性使用’.’。

1
2
3
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

合并以上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Employee:
'所有员工的基类'
empCount = 0

def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1 #注意这里的调用方式

def displayCount(self):
print "Total Employee %d" % Employee.empCount

def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary

"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount #特别注意这行代码的输出

输出结果:

1
2
3
Name :  Zara ,Salary:  2000
Name : Manni ,Salary: 5000
Total Employee 2 #特别注意这个值的输出

添加,删除,修改类的属性

1
2
3
emp1.age = 7  # 添加一个 'age' 属性
emp1.age = 8 # 修改 'age' 属性
del emp1.age # 删除 'age' 属性

用函数操作:

  • getattr(obj, name[, default]) : 访问对象的属性。

  • hasattr(obj,name) : 检查是否存在一个属性。

  • setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。

  • delattr(obj, name) : 删除属性。

1
2
3
4
5

hasattr(emp1, 'age') # 如果存在 'age' 属性返回 True
getattr(emp1, 'age') # 返回 'age' 属性的值
setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8
delattr(emp1, 'age') # 删除属性 'age'

内置类属性

  • dict : 类的属性(包含一个字典,由类的数据属性组成)

  • doc :类的文档字符串

  • name: 类名

  • module: 类定义所在的模块(类的全名是’main.className’,如果类位于一个导入模块mymod中,那么className.module 等于 mymod)

  • bases : 类的所有父类构成元素(包含了一个由所有父类组成的元组)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Employee:
'所有员工的基类'
empCount = 0

def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1

def displayCount(self):
print "Total Employee %d" % Employee.empCount

def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary

print "Employee.__doc__:", Employee.__doc__
print "Employee.__name__:", Employee.__name__
print "Employee.__module__:", Employee.__module__
print "Employee.__bases__:", Employee.__bases__
print "Employee.__dict__:", Employee.__dict__

代码输出:

1
2
3
4
5
Employee.__doc__: 所有员工的基类
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0x10a939c80>, 'empCount': 0, 'displayEmployee': <function displayEmployee at 0x10a93caa0>, '__doc__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__init__': <function __init__ at 0x10a939578>}