通过代码说明python中的OOP:
# 定义类 class Student: '这是Student的文档字符串' studentCount = 0; # 类变量,所有类的实例共享该变量
def __init__(self, name, age): # 构造函数 self.name = name; # 定义类的属性 self.age = age; # self代表类的实例本身 Student.studentCount += 1; # 类变量的访问方法:类名.类属性 return;
def showStudentCount(self): # 定义类的方法,self在定义类的方法时是必须有的,虽然调用的时候不需要 print "Student count:", Student.studentCount; return;
def displayInfo(self): print "Name:", self.name, "\nAge:", self.age; return;
# 定义继承类 class ClassMonitor(Student): def __init__(self): print "I am the class monitor"; return;
studentA = Student("Daniel", 18); # 创建一个类的实例,并初始化(调用构造函数) studentA.displayInfo(); # 调用类的方法 studentB = Student("Dan", 25); studentA.showStudentCount(); # 打印类属性 print studentB.name; print studentB.__class__.__name__; # 输出类的名称:Student
print hasattr(studentA, "name"); # hasattr(obj,name) : 检查是否存在一个属性。 print getattr(studentA, "nonexistattr", "default value"); # getattr(obj, name[, default]) : 访问对象的属性。 setattr(studentA, "nonexistattr", "haha, got u"); # setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。 if hasattr(studentA, "nonexistattr"): print getattr(studentA, "nonexistattr"); print hasattr(studentB, "nonexistattr"); print "B also got the attribute"; delattr(studentA, "nonexistattr"); # delattr(obj, name) : 删除属性。 if hasattr(studentA, "nonexistattr"): print getattr(studentA, "nonexistattr");
# python预定义的类属性 print "\n"; print Student.__dict__; # 包含一个字典类型,由类的属性组成 # 输出:{'displayInfo': <function displayInfo at 0x0000000002DE8F98>, '__module__': '__main__', # 'showStudentCount': <function showStudentCount at 0x0000000002DE8F28>, 'studentCount': 2, # '__doc__': None, '__init__': <function __init__ at 0x0000000002DE8EB8>}
print Student.__doc__; # 类的文档字符串 # 输出:这是Student的文档字符串
print Student.__name__; # 类名 # 输出:Student
print Student.__module__; # 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么 # className.__module__ 等于 mymod) # 输出:__main__
print ClassMonitor.__bases__; # 类的所有父类构成元素(包含了一个由所有父类组成的元组) # 输出:(<class __main__.Student at 0x0000000002E3BF48>,)
class DemoClass: def __init__(self): # 构造函数 print self.__class__.__name__, "constructed"; return;
def __del__(self): # 析构函数 print self.__class__.__name__, "destroyed"; return;
demo1 = DemoClass(); demo2 = DemoClass(); del demo1; del demo2;
# python支持多重继承,关于多重继承,会单独发一篇blog说明 # 1:在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。 # 2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数 # 3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
# issubclass() - 布尔函数判断一个类是另一个类的子类或者子孙类,语法:issubclass(sub,sup) # isinstance(obj, Class) 布尔函数如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true。
# super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题, # 但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。 # 总之经验就是:保持一致性。要不全部用类名调用父类,要不就全部用 super,不要一半一半。 class A(object): def __init__(self): print "A constructed"; return;
def fun(self): print "A fun"; return;
def __del__(self): print "A destroyed"; return;
class D(A): # D继承A def __init__(self): print "D constructed"; return;
def __del__(self): print "D destroyed"; return;
class B(object): def __init__(self): print "B constructed"; return;
def fun(self): print "B fun"; return;
def __del__(self): print "B destroyed"; return;
class C(D, B): # C继承D和B def __init__(self): A.__init__(self); # 使用类名调用父类方法 B.__init__(self); super(C, self).__init__(); # 使用super关键字调用父类方法 print "C constructed"; return;
def fun(self): super(C, self).fun(); print "Child fun"; return;
def __del__(self): print "C destroyed"; return;
c = C(); c.fun(); print c;
# 运算符重载 # python中可重载的二元运算符 # + __add__,__radd__ # - __sub__,__rsub__ # * __mul__,__rmul__ # / __div__,__rdiv__,__truediv__,__rtruediv__ # // __floordiv__,__rfloordiv__ # % __mod__,__rmod__ # ** __pow__,__rpow__ # << __lshift__,__rlshift__ # >> __rshift__,__rrshift__ # & __and__,__rand__ # ^ __xor__,__rxor__ # | __or__,__ror__ # += __iaddr__ # -= __isub__ # *= __imul__ # /= __idiv__,__itruediv__ # //= __ifloordiv__ # %= __imod__ # **= __ipow__ # <<= __ilshift__ # >>= __irshift__ # &= __iand__ # ^= __ixor__ # |= __ior__ # == __eq__ # !=,<> __ne__ # > __get__ # < __lt__ # >= __ge__ # <= __le__
class NumList(object): def __init__(self, num): self.numList = range(num); return;
def __pow__(self, num): # 重载幂运算符 for n in self.numList: n **= num; return;
def __str__(self): # 重载str(obj)方法 result = ""; for num in self.numList: result += str(num); return result;
def __cmp__(self, other): # 重载比较运算符 if self.numList[0] > other.numList[0]: return 1 elif self.numList[0] < other.numList[0]: return -1 else: return 0
nums = NumList(10); nums1 = NumList(10); nums ** 2; print nums; print nums1; print cmp(nums, nums1)
# 私有方法和属性(通过在标识符前面加__) class TestCls(object): __privateStr = "This is a static private attribute"; # 私有类属型 publicStr = "This is a static public attribute";
def __init__(self): self.publicAttr = "this is a public attribute"; self.__privateAttr = "This is a private attribute"; # 私有实例属性 print "constructor"; return;
def publicMethod(self): print "public method"; return;
def __privateMethod(self): # 私有方法 print "privte method"; return;
ts = TestCls(); print TestCls.publicStr; # print TestCls.__privateStr; #error print ts.publicAttr; # print ts.__privateAttr; #error ts.publicMethod(); # ts.__privateMethod(); #error |