Python从设计之初就已经是一门面向对象的语言。

定义类

  1. class ClassName:
  2. '类的帮助信息' #类文档字符串
  3. class_suite #类体
  4. ####################例子####################
  5. class Employee:
  6. '所有员工的基类'
  7. empCount = 0 #类变量,所有实例共享,类似C的静态变量。
  8. def __init__(self, name, salary): #构造函数
  9. #self: 类的实例,成员方法的第一个参数都必须是类的实例,
  10. # 名字并不一定非是self,重要的是它的含义
  11. # 调用时,不需要显式传入这个参数,类似lua的self
  12. #name salary: 构造参数,instance = Employee(name, salary)
  13. self.name = name
  14. self.salary = salary
  15. Employee.empCount += 1 #访问类变量
  16. def __del__(self): #析构函数,对象被销毁的时候调用。
  17. class_name = self.__class__.__name__
  18. print class_name, "销毁"
  19. def displayCount(self): #成员方法,第一个参数必须是self
  20. print Employee.empCount
  21. def displayEmployee(self): #成员方法,第一个参数必须是self
  22. print self.name, self.salary
  23. instance = Employee("Fucker", 10000)
  24. instance.displayCount()
  25. instance.displayEmployee()

访问属性

我们把成员函数叫方法,成员变量叫属性。
类的属性和局部变量一样的特性,“随用随建”,第一次赋值就是创建,无需像C++一样提前定义。
同名属性会覆盖方法。
按C++的理解,python中的所有方法都是virtual的,即都能多态。

  1. print(instance.name) # 访问已有属性
  2. instance.age = 7 # 添加一个 'age' 属性
  3. instance.age = 8 # 修改 'age' 属性
  4. del instance.age # 删除 'age' 属性
  5. hasattr(emp1, 'age') # 检查属性是否存在
  6. getattr(emp1, 'age') # 返回属性值
  7. setattr(emp1, 'age', 8) # 添加属性
  8. delattr(emp1, 'age') # 删除属性

访问权限

  • protected
    • _foo以单下划线开头命名的成员,和C++一样,只允许自己和子类内部访问。类的用户不能访问(创建对象的地方),不能用于from module import *。
  • private
    • __foo,以双下划线开头命名的成员,只有类内部可以访问。
  • public
    • 不以下划线开头命名的成员

由于存在对于类私有成员的有效使用场景(例如避免名称与子类所定义的名称相冲突),因此存在对此种机制的有限支持,称为 名称改写。 任何形式为 spam 的标识符(至少带有两个前缀下划线,至多一个后缀下划线)的文本将被替换为 _classnamespam,其中 classname 为去除了前缀下划线的当前类名称。 这种改写不考虑标识符的句法位置,只要它出现在类定义内部就会进行。

foo,这种命名方式的成员,一般都是python内置成员,有特殊含义,自定义成员最好不要这样取。
类对象的用户(类对象外部),可以通过如下方法访问到对象的私有属性:

  1. #可以通过object._className__attrName访问到对象的私有属性。
  2. #object: 对象
  3. #className: 类名
  4. #attrName: 属性名字
  5. class Fucker:
  6. __private = "private"
  7. fucker = Fucker()
  8. print fucker._Fucker__private #输出private

内置成员

内置属性

  • dict
    • 类的属性(包含一个字典,由类的数据属性组成)
  • doc
    • 类的文档字符串
  • name
    • 类名
  • module
    • 类定义所在的模块(类的全名是’main.className’,如果类位于一个导入模块mymod中,那么className.module 等于 mymod)
  • bases
    • 类的所有父类构成元素(包含了一个由所有父类组成的元组) ```python 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
################输出如下

Employee.doc: 所有员工的基类 Employee.name: Employee Employee.module: main Employee.bases: () Employee.dict: { ‘module‘: ‘main‘, ‘displayCount’: , ‘empCount’: 0, ‘displayEmployee’: , ‘doc‘: ‘\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb’, ‘init‘: }

  1. <a name="pDcB2"></a>
  2. ## 内置方法
  3. ```python
  4. __init__ ( self [,args...] )
  5. #构造函数
  6. #简单的调用方法: obj = className(args)、
  7. __del__( self )
  8. #析构方法, 删除一个对象
  9. #简单的调用方法 : del obj
  10. __repr__( self )
  11. #转化为供解释器读取的形式
  12. #简单的调用方法 : repr(obj)
  13. __str__( self )
  14. #用于将值转化为适于人阅读的形式
  15. #简单的调用方法 : str(obj)
  16. __cmp__ ( self, x )
  17. #对象比较
  18. #简单的调用方法 : cmp(obj, x)

继承

  1. class DerivedClass(BaseClass): #DerivedClass继承自BaseClass
  2. #(BaseClass)继承元组,可以多个元素,也就是多重继承
  3. pass
  4. ##########################例子
  5. class Base: #父类
  6. baseAttr = 100
  7. def __init__(self):
  8. print "调用父类构造函数"
  9. def baseMethod(self):
  10. print '调用父类方法'
  11. def setAttr(self, attr):
  12. Parent.baseAttr = attr
  13. def getAttr(self):
  14. print "父类属性 :", Base.baseAttr
  15. class Derived(Base): # Derived继承Base
  16. def __init__(self):
  17. print "调用子类构造方法"
  18. def derivedMethod(self):
  19. print '调用子类方法'
  20. def baseMethod(self):
  21. Base.baseMethod(self) #调用父类的同名方法
  22. print("调用子类方法")
  23. d = Derived() # 实例化子类
  24. d.derivedMethod() # 调用子类的方法
  25. d.baseMethod() # 调用父类方法
  26. # 调用子类方法
  27. d.setAttr(200) # 再次调用父类的方法 - 设置属性值
  28. d.getAttr() # 再次调用父类的方法 - 获取属性值
  29. #常用内置函数
  30. issubclass(derived, base) #base是否是(间接)基类,不一定要是直接基类。
  31. isinstance(obj, Class) #obj是否是Class(子)类的对象。
  32. #obj.__class__

多重继承

在最简单的情况下,可以认为搜索从父类所继承属性的操作是深度优先、从左至右的。当层次结构中存在重叠时不会在同一个类中搜索两次。(菱形继承)

运算符重载

  1. def __str__(self): #print(a)触发
  2. pass
  3. def __add__(self,other): #a + b触发
  4. pass