构造函数、析构函数
__init__ (self) # 在继承体系中,如果父类有__init__函数,子类必须在__init__函数中显式的调用父类的__init__函数来初始化
__del__ (self)
类的静态变量
class Student
name = " abc "
初始化类的静态变量是这样的 (DiveIntoPython中的例子)
class counter:
count = 0
def __init__ (self):
self. __class__ .count += 1
c = counter() # 产生一个实例
print (c.count) # 1
print (counter.count) # 1
counter.count = 3 ; # 通过类修改 3
print (c.count) # 3
print (counter.count) # 3
c. __class__ .count = 4 # 通过类修改
print (c.count) # 4
print (counter.count) # 4
c. count = 5 # 通过实例修改
print (c.count) # 5
print (counter.count) # 4 类的静态变量无法通过实例修改
实例的成员变量
class Student
def __init__ (self)
self.name = " abc "
属性定义
class Student:
def __init__ (self):
self. __name = " abc "
def GetName(self):
return self. __name
def SetName(self,value):
self. __name = value
def DelName(self):
del self. __name
Name = property(GetName,SetName,DelName, ' Student name ' )
只读属性(类必须从object继承,否则就不是只读的)在python 3000中所有的类都是从object继承的,就不存在这个问题了。
class Parrot(object):
def __init__ (self):
self. __voltage = 100000
@property
def voltage(self):
""" Get the current voltage. """
return self. __voltage
私有变量
class Student:
def __init__ (self):
self. __name = " abc " # 很简单就是通过__两个下划线开头,但不是结尾的。就是私有了
私有方法
class Student:
def __Getage (self):
pass
# 和私有的变量一样,你可以尝试一下直接调用,编译器会有相应的提示
强制访问私有方法、变量,"私有"事实上这只是一种规则,我们依然可以用特殊的语法来访问私有成员。上面的方法,我们就可以通过_类名来访问
aobj = Student()
aobj._Student__name
aobj._Student__Getage()
静态方法
class Class1:
@staticmethod
def test():
print " In Static method... "
方法重载
python是不支持方法重载,但是你代码了里可以写。Python会使用位置在最后的一个。我觉得这可能以Python存储这些信息通过__dict__ 有关,它就是一个Dict。key是不能相同的。所以也就没办法出现两个GoGo 方法调用。
class Student:
def GoGo(self,name):
print name
def GoGo(self):
print " default "
s = Student()
s.GoGo() # 只能使用到方法最下面的一个函数
Student.GoGo( ' hello ' ) # 这里可以用类直接调用,但是需要加入一个参数来填 self,虽然这个参数本身不起作用
>>>
default
default
本质上,调用的时候你只能使用后面那个GoGo()方法。
一些特殊方法
__init__ (self) 构造函数
__del__ (self) 析构函数
__repr__ ( self) repr()
__str__ ( self) print语句 或 str()
运算符重载
__lt__ ( self, other)
__le__ ( self, other)
__eq__ ( self, other)
__ne__ ( self, other)
__gt__ ( self, other)
__ge__ ( self, other)
这东西太多了。大家还是自己看Python自带帮助吧。
一些特殊属性,当你定义一个类和调用类的实例时可以获得的一些默认属性 。
class Student:
''' this test class '''
name = ' ss '
def __init__ (self):
self.name = ' bb '
def Run(self):
''' people Run '''
@staticmethod
def RunStatic():
print " In Static method... "
print Student. __dict__ # 类的成员信息
print Student. __doc__ # 类的说明
print Student. __name__ # 类的名称
print Student. __module__ # 类所在的模块
print Student. __bases__ # 类的继承信息
obj = Student()
print dir(obj)
print obj. __dict__ # 实例的成员变量信息(不太理解Python的这个模型,为什么 Run这个函数却不再dict中)
print obj. __doc__ # 实例的说明
print obj. __module__ # 实例所在的模块
print obj. __class__ # 实例所在的类名
具体的语法就不说了。我很关心的是它到底继承了什么单继承条件下很简单。类的静态变量、类的静态方法、实例的方法、实例的成员变量、基类的构造函数、基类的析构函数都可以从父类中继承过来。私有方法和私有变量是不能继承的。具体看测试代码:
class Student:
''' this test class '''
name = ' ss '
age = 13
def __init__ (self):
self.name = ' bb '
self.addr = " shanghai "
self. __love = " man "
print " init... "
def __del__ (self):
print " dead... "
def Run(self):
print ' people Run '
@staticmethod
def RunStatic():
print " In Static method... "
def __Good (self):
print " good "
class MiniStudent(Student):
pass
# 类
print MiniStudent.name
print MiniStudent.age
print MiniStudent.RunStatic()
print " ----================-------- "
# 实例
mini = MiniStudent()
print mini.name
print mini.age
print mini.Run()
print mini.addr
多继承下,情况明显比这复杂而且,而且会产生多个基类覆盖函数的问题。C++的多重继承在实际工程中使用也不多(过于复杂)。正因为这样,我感觉这种多继承应该一般不需要用,否则代码会很晦涩。下面这个例子你就可以看到。在上面的例子中,我多添加了一个StudentA的类。 具体看测试代码:
class StudentA:
def __init__ (self):
print ' init-studenta '
def GoCar(self):
print " Go Car "
class Student:
''' this test class '''
name = ' ss '
age = 13
def __init__ (self):
self.name = ' bb '
self.addr = " shanghai "
self. __love = " man "
print " init... "
def __del__ (self):
print " dead... "
def Run(self):
print ' people Run '
@staticmethod
def RunStatic():
print " In Static method... "
def __Good (self):
print " good "
class MiniStudent(Student,StudentA):
pass
# 类
mini = MiniStudent()
print mini.name
print mini.age
print mini.Run()
print mini.addr
现在这个例子是可以通过的,但如果你把class MiniStudent(Student,StudentA)修改成class MiniStudent(StudentA,Student)这个代码就通不过了。告诉你mini.addr没有定义。其实是StudentA的构造函数覆写了Student的函数,也就是说只调用了StudentA.__init__()的方法。下面就谈到继承中的覆写问题。
从上面的经验可以得到Python的多继承,但有以下几点需要注意:
1. 继承方法的调用和基类声明顺序有关(排在前面的覆写后面的方法)。
2. 基类init、del ,如果希望都使用,请显示的调用,否则很容易出错。
class StudentA:
def __init__ (self):
print ' init-b '
class Student:
def __init__ (self):
print ' init-a '
class MiniStudent(Student,StudentA):
def __init__ (self):
StudentA. __init__ (self)
Student. __init__ (self)
# 实例
mini = MiniStudent()