1 #!/usr/bin/python
 2 # -*- coding: UTF-8 -*-
 3  
 4 class Employee:
 5    '所有员工的基类'
 6    empCount = 0
 7  
 8    def __init__(self, name, salary):
 9       self.name = name
10       self.salary = salary
11       Employee.empCount += 1
12    
13    def displayCount(self):
14      print "Total Employee %d" % Employee.empCount
15  
16    def displayEmployee(self):
17       print "Name : ", self.name,  ", Salary: ", self.salary

empCount 变量是一个类变量,它的值将在这个类的所有实例之间共享。你可以在内部类或外部类使用 Employee.empCount 访问。

1 >>> fff = Employee('fff','100000')
2 >>> fff.displayCount()
3 Total Employee 1
4 >>> zzj=Employee('zzj','1000')
5 >>> zzj.displayCount()
6 Total Employee 2
7 >>> 

 

self代表类的实例,而非类

类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。


1
class Test: 2 def prt(self): 3 print(self) 4 print(self.__class__) 5 t = Test() 6 t.prt()

结果

<__main__.Test instance at 0x10d066878>
__main__.Test

从执行结果可以很明显的看出,self 代表的是类的实例,代表当前对象的地址,而 self.class 则指向类

 

 

 

 

#!/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

执行

Name :  Zara ,Salary:  2000
Name :  Manni ,Salary:  5000
Total Employee 2
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) : 删除属性。
 
hasattr(emp1, 'age')    # 如果存在 'age' 属性返回 True。
getattr(emp1, 'age')    # 返回 'age' 属性的值
setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8
delattr(empl, 'age')    # 删除属性 'age'

Python内置类属性

  • __dict__ : 类的属性(包含一个字典,由类的数据属性组成)
  • __doc__ :类的文档字符串
  • __name__: 类名
  • __module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
  • __bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)

Python内置类属性调用实例如下:

 1 #!/usr/bin/python
 2 # -*- coding: UTF-8 -*-
 3  
 4 class Employee:
 5    '所有员工的基类'
 6    empCount = 0
 7  
 8    def __init__(self, name, salary):
 9       self.name = name
10       self.salary = salary
11       Employee.empCount += 1
12    
13    def displayCount(self):
14      print "Total Employee %d" % Employee.empCount
15  
16    def displayEmployee(self):
17       print "Name : ", self.name,  ", Salary: ", self.salary
18  
19 print "Employee.__doc__:", Employee.__doc__
20 print "Employee.__name__:", Employee.__name__
21 print "Employee.__module__:", Employee.__module__
22 print "Employee.__bases__:", Employee.__bases__
23 print "Employee.__dict__:", Employee.__dict__

 

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>}

 

继承:

在python中继承中的一些特点:

  • 1:在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。
  • 2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数
  • 3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。

你可以使用issubclass()或者isinstance()方法来检测。

  • issubclass() - 布尔函数判断一个类是另一个类的子类或者子孙类,语法:issubclass(sub,sup)
  • isinstance(obj, Class) 布尔函数如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true。

 

基础重载方法

下表列出了一些通用的功能,你可以在自己的类重写:

序号方法, 描述 & 简单的调用
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)

 

 

运算符重载

Python同样支持运算符重载,实例如下:

 1 #!/usr/bin/python
 2  
 3 class Vector:
 4    def __init__(self, a, b):
 5       self.a = a
 6       self.b = b
 7  
 8    def __str__(self):
 9       return 'Vector (%d, %d)' % (self.a, self.b)
10    
11    def __add__(self,other):
12       return Vector(self.a + other.a, self.b + other.b)
13  
14 v1 = Vector(2,10)
15 v2 = Vector(5,-2)
16 print v1 + v2

执行

以上代码执行结果如下所示:

Vector(7,8)

类的私有方法

__private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用 self.__private_methods

 1 #!/usr/bin/python
 2 # -*- coding: UTF-8 -*-
 3  
 4 class JustCounter:
 5     __secretCount = 0  # 私有变量
 6     publicCount = 0    # 公开变量
 7  
 8     def count(self):
 9         self.__secretCount += 1
10         self.publicCount += 1
11         print self.__secretCount
12  
13 counter = JustCounter()
14 counter.count()
15 counter.count()
16 print counter.publicCount
17 print counter.__secretCount  # 报错,实例不能访问私有变量

单下划线、双下划线、头尾双下划线说明:

  • __foo__: 定义的是特列方法,类似 __init__() 之类的。

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

  • __foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。

测试实例:

 1 #!/usr/bin/python
 2 # -*- coding: UTF-8 -*-
 3 
 4 class JustCounter:
 5     __secretCount = 0  # 私有变量
 6     publicCount = 0    # 公开变量
 7     def count(self):
 8         self.__secretCount += 1
 9         self.publicCount += 1
10         print self.__secretCount
11     def count2(self):
12         print self.__secretCount
13 
14 counter = JustCounter()
15 counter.count()
16 # 在类的对象生成后,调用含有类私有属性的函数时就可以使用到私有属性.
17 counter.count()
18 #第二次同样可以.
19 print counter.publicCount
20 print counter._JustCounter__secretCount  # 不改写报错,实例不能访问私有变量
21 try:
22     counter.count2()
23 except IOError:
24     print "不能调用非公有属性!"
25 else:
26     print "ok!" #现在呢!证明是滴!