持续更新中
通过“对象。成员”的方式来访问其中的数据或成员方法
class Car: #定义类
def infor(self): #成员方法
print("This is a car")
#实例化对象
car=Car()
car.infor()
#在Python中,可以使用内置函数instance()来测试一个对象是否为某个类的实例,返回True或False
isinstance(car,Car)
pass表示空语句
class A:
pass
def demo():
pass
if 5>3:
pass
类的所有实例方法都至少有一个名为self的参数,并且必须是方法的一个形参(如果有多个形参),self参数表示对象本身。在类的实例方法中访问实例属性时需要以self为前缀,但在外部通过对象名方法时并不需要传递这个参数,如果在外部通过类名调用对象方法则需要显式为self参数传递该类的一个对象
1.实例属性:一般在构造方法__init()__()中定义的,定义和使用时必须以self作为前缀;
2.类属性:在类中所有方法之外定义的数据成员
在主程序中(或类的外部),实例属性属于实例(对象),只能通过对象名访问;
而类属性属于类,可以通过类名或对象名访问
在Python中,可以动态地为类和对象增加成员,这一点是和很多面向对象程序设计不同的,也是Python动态类型特点的一种重要体现
import types
class Car:
price = 100000 #定义类属性
def __init__(self,c):
self.color=c #定义实例属性
car1=Car("Red")
car2=Car("Blue")
print(car1.color,Car.price)
Car.price=199999 #修改类属性
Car.name='QQ' #增加类属性
car1.color="Yellow" #修改实例属性
print(car2.color,Car.price,Car.name)
print(car1.color,Car.price,Car.name)
def setSpeed(self,s):
self.speed=s
car1.setSpeed=types.MethodType(setSpeed,car1) #动态为对象增加成员方法
car1.setSpeed(50) #调用对象的成员方法
如果成员名以两个下划线开头但不以两个下划线结尾,则表示是私有对象。
私有对象在类的外部不能直接访问,需要调用对象的公有成员方法来访问,或者通过Python支持的特殊方式来访问
公有对象可以公开使用,既可以在类的内部进行访问,也可以在外部程序中使用
class A:
def __init__(self,value1=0,value2=0):
self.value1=value1
self.__value2=value2 #私有数据对象
def __setValue__(self,value1, value2):
self.value1=value1 #这句删除后结果不变
self.__value2=value2 #在成员方法中访问私有数据对象
def show(self):
print(self.value1)
print(self.__value2)
a=A()
a.value1
a._A__value2
在Python中,带下划线的变量名和方法名有特殊的含义,尤其是在类的定义中。
用下划线作为变量名和方法名前缀名和后缀来表示类的特殊成员
在类中定义的方法可以粗略分为四大类:公有方法、私有方法、静态方法和类方法。
公有方法通过对象名直接调用
私有方法不能通过对象名直接调用,只能在属于对象的方法中通过 self 调用或在外部通过 Python 支持的特殊方式来调用。
如果通过类名来调用属于对象的公有方法,需要显式为该方法的 self 参数传递一个对象名,用来明确指定访问哪个对象的数据成员。
静态方法和类方法都可以通过类名和对象名调用,但不能直接访问属于对象的成员,只能访问属于类的成员。
一般将 cls 作为类方法的第一个参数名称,但也可以使用其他的名字(不建议这样做)作为参数,并且在调用类方法时不需要为该参数传递值。例如:
class Root:
__total=0 #属于类的私有数据对象
def __init__(self,v):
self.__value=v
Root.__total+=1
def show(self): #普通实例方法
print('self.__value:',self.__value)
print('Root.__tatal:',Root.__total)
@classmethod #修饰器
def classShowTotal(cls): #类方法
print(cls.__total)
@staticmethod
def staticShowTotal(): #静态方法
print(Root.__total) #静态方法可以访问类的成员,但要使用类的名字作为前缀
r=Root(3)
r.classShowTotal() #通过对象调用类方法
r.staticShowTotal() #通过对象来调用静态方法
r.show() #通过对象来调用对象的公有成员方法
rr=Root(5)
Root.classShowTotal()
Root.staticShowTotal()
Root.show() #试图通过类名直接调用
Root.show(r) #但是通过这种方法来调用方法并访问实例成员
Root.show(rr) #通过类名调用实例方法时为self参数显示传递对象名
class Test:
def __init__(self,value):
self.__value=value
@property #修饰器,定义属性
def value(self): #只读,无法修改和删除
return self.__value
t=Test(3)
t.value
t.value=5 #只读属性不允许修改值
t.v=5 #动态增加新成员,和只读属性
t.v
del t.v #动态删除成员
del t.value #试图删除对象的只读属性,失败
t.value
下面的代码把属性设置为可读、可修改,而不允许删除
class Test:
def __init__(self,value):
self.__value=value
def __get(self): #访问属性时调用的方法
return self.__value
def __set(self,v): #修改属性时调用的方法
self.__value=v
value=property(__get,__set) #修饰器,定义可读可写属性
def show(self): #普通成员方法
print(self.__value)
t=Test(3)
t.value #允许读取属性值
t.value=5 #允许修改属性值
t.value
t.show() #属性对应的私有变量也得到了相应的修改
del t.value #试图删除属性,失败
当然,也可以将属性设置为可读、可修改、可删除
class Test:
def __init__(self,value):
self.__value=value
def __get(self):
return self.__value
def __set(self,v):
self.__value=v
def __del(self): #删除属性时调用的方法
del self.__value #删除对应的私有数据成员
value=property(__get,__set,__del)
def show(self):
print(self.__value)
t=Test(3)
t.show()
t.value
t.value=5
t.show()
t.value
del t.value #删除对象属性及其对应的私有数据成员
t.value
t.show()
t.value=1
t.value
t.show()
示例: 在派生类中调用基类方法
首先设计Person类,然后以Person为基类派生Teacher类,分别创建Person类和Teacher类的对象,并在派生类对象中调用基类方法
class Person(object):
def __init__(self,name='',age=20,sex='man'):
self.setName(name)
self.setAge(age)
self.setSex(sex)
def setName(self,name):
if not isinstance(name,str): #判断name是不是string类型
print('name must be string')
return
self.__name=name
def setAge(self,age):
if not isinstance(age,int):
print('age must be int')
return
self.__age=age
def setSex(self,sex):
if sex not in('man','woman'):
print('sex must be "man"or"woman"')
return
self.__sex=sex
def show(self):
print('Name:',self.__name)
print('Age:',self.__age)
print('Sex:',self.__sex)
class Teacher(Person): #派生类
def __init__(self,name='',age=30,sex='man',departmant='Computer'):
super(Teacher, self).__init__(name, age, sex)
#也可以使用下面的形式对基类数据成员进行初始化
#Person.__init__(self, name, age, sex) #使用基类方法进行初始化
self.setDepartment(departmant)
def setDepartment(self,department):
if not isinstance(department,str):
print('department must be a string.')
return
self.__department=department
def show(self):
super(Teacher, self).show()
print('Department:',self.__department)
if __name__=='__main__':
zhangsan=Person('Zhangsan San')
zhangsan.show()
lisi=Teacher('Li Si',32,'man','Math')
lisi.show()
lisi.setAge(40)
lisi.show()
编译结果:
为了更好地理解Python类的继承机制,再来看下面的代码,并认真体会构造方法、私有方法和普通公开方法的继承原理
class A(object):
def __init__(self):
self.__private()
self.public()
def __private(self):
print('__private() method in A')
def public(self):
print('public() method in A')
class B(A): #注意,类B没有定义构造方法
def __private(self):
print('__private() method in A')
def public(self):
print('public() method in B')
b=B()
dir(B)
class C(A):
def __init__(self): #显示定义构造方法,覆盖率A类中的构造方法
self.__private()
self.public()
def __private(self):
print('__private() method in C')
def public(self):
print('public() method in C')
c=C()
dir(c)
dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。