【Python】类——面向对象
Python类
格式
1 | class Student (): |
变量
刻画特征
类变量
为所有实例共享
类名.变量名 # 调用类变量
实例变量
为每个实例所独有:保存对象特征值
对象名.变量名 # 调用实例变量
请看下面的栗子
1 | class Student (): |
list
liufang
zhangsan
注
在Student类中定义“名字”,“年龄”两个变量没有错误但没有意义
因为类是抽象的客观,而类变量中的“名字”,“年龄”应该是具体的,所以应该是属于具体对象中的,因此应该在实例变量中定义“名字”“年龄”,使它们与对象关联起来。
类变量意义所在↓
1 | class Student (): |
2 # 通过构造函数的调用次数累加类变量total(不会根据不同对象而初始化改变),反映输入学生个数的总数
方法
描述行为,通常对变量进行运算和逻辑上的一些操作
实例方法
一、定义与调用:
- 定义实例方法时,需要传入self参数
- 调用实例方法时,不需要传入self参数
二、变量访问:
访问类变量:
- 不能直接使用类变量名
两种访问方式
类名.变量名 self.__class__.变量名 # __class__关键字指当前类
访问实例变量
self.变量名 # 实例方法中只能通过self.变量名调用实例变量,读取操作实例变量
误区:不能只通过访问self后面的变量名来访问
举个栗子↓
1
2
3
4
5
6
7
8class Student ():
def __init__(self,n,a):
self.name=n
self.age=a
print(self.name)
print(self.__dict__)
print(name)
stu1=Student("lisi",20)lisi #执行第一个print函数 {'name': 'lisi', 'age': 20} #执行第二个print函数,显示变量的字典,存在name变量名 **报错** #但执行第三个print通过使用name变量名仍然会报错
self“关键字”:
- python中强制显示(显胜于隐),形如C++中的this指针
- 可以改成任意内容(推荐self)
- self参数就代表了当前调用某个方法的对象
- 只和对象有关,与类无关(代表实例,不代表类)
类方法
专门操作类变量的方法
1 |
|
一、定义与调用:
定义类方法:
- @classmethod:装饰器
- 关键字参数推荐为cls(class简写):代表当前类的参数
调用类方法:
类名.类方法 # 推荐 对象名.类方法 # 不推荐
二、变量访问:
访问类变量
cls.类变量名
不能访问实例变量
三、一个栗子:
将前面实现学生总数统计(类变量的意义)的代码放到类方法中操作↓
1 | class Student (): |
2
静态方法
1 |
|
- 定义与调用:
- 无需传递指定的参数
- 对象和类都可调用静态方法
- 变量访问:
- 静态方法内部可以访问类变量
- 不能访问实例变量
成员可见性
设置私有数据
编程提倡规范:对于对类内数据成员的更改赋值,应调用相应的赋值方法,而不是类外直接访问赋值
1 | class Student (): |
100
阻止别人在类外赋值:
python变量私有化:双下划线+变量名/方法名
__变量名
__方法名
1 | class Student(): |
**报错** # 因为无法访问方法和实例变量
注
双下划线+init+双下划线构造函数可以类外访问,因为当存在 双下划线+变量/方法名+双下划线 结构时,python认为可以访问
类外强制访问私有数据
进阶↓1
2
3
4
5
6
7
8
9
10class Student():
def __init__(self,n,a):
self.__name=n
self.__age=a
self.__score=60
def __printer(self):
print(self.__name)
stu1=Student("zhangsan",20)
stu1.__score=-1
print(stu1.__score)
-1
“事实”证明:类外不仅能对类内__score变量强制赋值还能强制访问??
解析!!!
并不是score私有化没有生效,而是因为python的动态性原因,而使stu1对象中新生成了变量”__score”,而后对新的普通值进行了读取
1 | print(stu1.__dict__) # 输出stu1对象的字典检查其内部数据 |
-1
{'_Student__name': 'zhangsan', '_Student__age': 20, '_Student__score':60, '__score': -1}
输出的字典中,”zhangsan”是类私有成员,”__socre”是强行新定义的动态添加的变量。
python在检查到私有变量后会改变变量的名称:单下划线+类名+双下划线+变量名
_类名__变量名
这也是为什么在类外无法通过”__变量名”访问类的私有变量,因为名称已被python改变,输入原来变量名是无效的
因此
只要通过读取python改变的新的变量名就可以访问私有数据成员!!1
print(stu1._Student__score) # 访问新的名字
60
继承性
作用:避免定义重复的语法和重复的变量
形式:
1 | class Human(): |
构造函数的继承
super(子类名,self).__init__(父类构造函数形参)
父类名.__init__(self,父类构造参数形参)
super关键字:
不仅可在子类构造函数中使用,也可在子类实例方法使用。
1 | class Human(): |
this is parent class
this is subclass
面向对象三大特性:
- 继承性
- 封装性
- 多态性