定义类
class ClassName:'类的帮助信息' #类文档字符串class_suite #类体####################例子####################class Employee:'所有员工的基类'empCount = 0 #类变量,所有实例共享,类似C的静态变量。def __init__(self, name, salary): #构造函数#self: 类的实例,成员方法的第一个参数都必须是类的实例,# 名字并不一定非是self,重要的是它的含义# 调用时,不需要显式传入这个参数,类似lua的self#name salary: 构造参数,instance = Employee(name, salary)self.name = nameself.salary = salaryEmployee.empCount += 1 #访问类变量def __del__(self): #析构函数,对象被销毁的时候调用。class_name = self.__class__.__name__print class_name, "销毁"def displayCount(self): #成员方法,第一个参数必须是selfprint Employee.empCountdef displayEmployee(self): #成员方法,第一个参数必须是selfprint self.name, self.salaryinstance = Employee("Fucker", 10000)instance.displayCount()instance.displayEmployee()
访问属性
我们把成员函数叫方法,成员变量叫属性。
类的属性和局部变量一样的特性,“随用随建”,第一次赋值就是创建,无需像C++一样提前定义。
同名属性会覆盖方法。
按C++的理解,python中的所有方法都是virtual的,即都能多态。
print(instance.name) # 访问已有属性instance.age = 7 # 添加一个 'age' 属性instance.age = 8 # 修改 'age' 属性del instance.age # 删除 'age' 属性hasattr(emp1, 'age') # 检查属性是否存在getattr(emp1, 'age') # 返回属性值setattr(emp1, 'age', 8) # 添加属性delattr(emp1, 'age') # 删除属性
访问权限
- protected
- _foo,以单下划线开头命名的成员,和C++一样,只允许自己和子类内部访问。类的用户不能访问(创建对象的地方),不能用于from module import *。
- private
- __foo,以双下划线开头命名的成员,只有类内部可以访问。
- public
- 不以下划线开头命名的成员
由于存在对于类私有成员的有效使用场景(例如避免名称与子类所定义的名称相冲突),因此存在对此种机制的有限支持,称为 名称改写。 任何形式为 spam 的标识符(至少带有两个前缀下划线,至多一个后缀下划线)的文本将被替换为 _classnamespam,其中 classname 为去除了前缀下划线的当前类名称。 这种改写不考虑标识符的句法位置,只要它出现在类定义内部就会进行。
foo,这种命名方式的成员,一般都是python内置成员,有特殊含义,自定义成员最好不要这样取。
类对象的用户(类对象外部),可以通过如下方法访问到对象的私有属性:
#可以通过object._className__attrName访问到对象的私有属性。#object: 对象#className: 类名#attrName: 属性名字class Fucker:__private = "private"fucker = Fucker()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’:
<a name="pDcB2"></a>## 内置方法```python__init__ ( self [,args...] )#构造函数#简单的调用方法: obj = className(args)、__del__( self )#析构方法, 删除一个对象#简单的调用方法 : del obj__repr__( self )#转化为供解释器读取的形式#简单的调用方法 : repr(obj)__str__( self )#用于将值转化为适于人阅读的形式#简单的调用方法 : str(obj)__cmp__ ( self, x )#对象比较#简单的调用方法 : cmp(obj, x)
继承
class DerivedClass(BaseClass): #DerivedClass继承自BaseClass#(BaseClass)继承元组,可以多个元素,也就是多重继承pass##########################例子class Base: #父类baseAttr = 100def __init__(self):print "调用父类构造函数"def baseMethod(self):print '调用父类方法'def setAttr(self, attr):Parent.baseAttr = attrdef getAttr(self):print "父类属性 :", Base.baseAttrclass Derived(Base): # Derived继承Basedef __init__(self):print "调用子类构造方法"def derivedMethod(self):print '调用子类方法'def baseMethod(self):Base.baseMethod(self) #调用父类的同名方法print("调用子类方法")d = Derived() # 实例化子类d.derivedMethod() # 调用子类的方法d.baseMethod() # 调用父类方法# 调用子类方法d.setAttr(200) # 再次调用父类的方法 - 设置属性值d.getAttr() # 再次调用父类的方法 - 获取属性值#常用内置函数issubclass(derived, base) #base是否是(间接)基类,不一定要是直接基类。isinstance(obj, Class) #obj是否是Class(子)类的对象。#obj.__class__
多重继承
在最简单的情况下,可以认为搜索从父类所继承属性的操作是深度优先、从左至右的。当层次结构中存在重叠时不会在同一个类中搜索两次。(菱形继承)
运算符重载
def __str__(self): #print(a)触发passdef __add__(self,other): #a + b触发pass
