Python使用class关键字来定义类,class关键字之后是一个空格,然后是类的名字,再然后是一个冒号,最后换行并定义类的内部实现。
类名的首字母一般要大写,当然也可以按照自己的习惯定 义类名,但一般推荐参考惯例来命名,并在整个系统的设 计和实现中保持风格一致,这一点对于团队合作尤其重要。
class Car:
def infor(self):
print(" This is a car ")
定义了类之后,可以用来实例化对象,并通过“对象名. 成员”的方式来访问其中的数据成员或成员方法。
>>> car = Car()
>>> ()
This is a car
Python提供了一个关键字“pass”,类似于空语句,可以 用在类和函数的定义中或者选择结构中。当暂时没有确定 如何实现功能,或者为以后的软件升级预留空间,或者其 他类型功能时,可以使用该关键字来“占位”。
>>> class A:
pass
>>> def demo():
pass
>>> if 5>3:
pass
self参数
类的所有实例方法都必须至少有一个名为self的参数,并 且必须是方法的第一个形参(如果有多个形参的话), self参数代表将来要创建的对象本身。
在类的实例方法中访问实例属性时需要以self为前缀。
在外部通过对象名调用对象方法时并不需要传递这个参数。
如果在外部通过类名调用对象方法则需要显式为self参数 传值。
在Python中,在类中定义实例方法时将第一个参数定义为 “self”只是一个习惯,而实际上类的实例方法中第一个参 数的名字是可以变化的,而不必须使用“self”这个名字, 尽管如此,建议编写代码时仍以self作为方法的第一个参 数名字。
>>> class A:
def __init__(hahaha, v):
= v
def show(hahaha):
print()
>>> a = A(3)
>>> ()
3
类成员与实例成员
属于实例的数据成员一般是指在构造函数__init__()中定义 的,定义和使用时必须以self作为前缀;属于类的数据成 员是在类中所有方法之外定义的。
在主程序中(或类的外部),实例属性属于实例(对象), 只能通过对象名访问;而类属性属于类,可以通过类名或 对象名都可以访问。
在实例方法中可以调用该实例的其他方法,也可以访问类属性以及实例属性。
在Python中比较特殊的是,可以动态地为类和对象增加成员,这一点是和很多面向对象程序设计语言不同的,也是 Python动态类型特点的一种重要体现。
class Car:
price = 100000 #定义类属性
def __init__(self, c):
= c #定义实例属性
car1 = Car("Red") #实例化对象
car2 = Car("Blue")
print(, ) #查看实例属性和类属性的值
= 110000 #修改类属性
= 'QQ' #动态增加类属性
= "Yellow" #修改实例属性
print(, , )
print(, , )
import types
def setSpeed(self, s):
= s
= (setSpeed, car1) #动态增加成员方法
(50) #调用成员方法
print()
import types
class Person(object):
def __init__(self, name):
assert isinstance(name, str), 'name must be string'
= name
def sing(self):
print(+' can sing.')
def walk(self):
print(+' can walk.')
def eat(self):
print(+' can eat.')
>>> zhang = Person('zhang')
>>> () #用户不具有该行为
AttributeError: 'Person' object has no attribute 'sing'
>>> = (sing, zhang)#动态增加一个新行为
>>> ()
zhang can sing.
>>> ()
AttributeError: 'Person' object has no attribute 'walk'
>>> = (walk, zhang)
>>> ()
zhang can walk.
>>> del #删除用户行为
>>> ()
AttributeError: 'Person' object has no attribute 'walk'
私有成员与公有成员
Python并没有对私有成员提供严格的访问保护机制。
在定义类的成员时,如果成员名以两个下划线“__”或更多下划线开头而不以两个或更多下划线结束则表示是私有成员。
私有成员在类的外部不能直接访问,需要通过调用对象的公开成员方法来访问,也可以通过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)
在Python中,以下划线开头的变量名和方法名有特殊的含 义,尤其是在类的定义中。用下划线作为变量名和方法名 前缀和后缀来表示类的特殊成员:
_xxx:受保护成员,不能用'from module import *'导入;
__xxx__:系统定义的特殊成员;
__xxx:私有成员,只有类对象自己能访问,子类对象不能直接访问到这 个成员,但在对象外部可以通过“对象名._类名__xxx”这样的特殊方式来访问。
注意: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.__total:', Root.__total)
@classmethod #修饰器,声明类方法
def classShowTotal(cls): #类方法
print(cls.__total)
@staticmethod #修饰器,声明静态方法
def staticShowTotal(): #静态方法
print(Root.__total)
>>> r = Root(3)
>>> () #通过对象来调用类方法
1
>>> () #通过对象来调用静态方法
1
>>> ()
self.__value: 3
Root.__total: 1
>>> rr = Root(5)
>>> () #通过类名调用类方法
2
>>> () #通过类名调用静态方法
2
属性
只读属性
class Test:
def __init__(self, value):
self.__value = value
@property
def value(self): #只读,无法修改和删除
return self.__value
>>> t = Test(3)
>>>
3
>>> = 5 #只读属性不允许修改值
AttributeError: can't set attribute
•可读、可写属性
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)
>>> #允许读取属性值
3
>>> = 5 #允许修改属性值
>>>
5
>>> () #属性对应的私有变量也得到了相应的修改
5