8、Python类
类的命名规范:
- 类名的首字母大写
- 不建议使用_来连接多单词的类名
#标准类的书写方式
class Student():
name = ''
age = 18
def out(self): #方法必须添加self参数
print(self.name + str(self.age)) #使用自身的参数
#类的实例化
student = Student()
#调用类下面的方法
student.out()
错误(当变量名调用出错):self.name 写成 name
类的易错点:
1. 类内不能运行类内的方法
类的设计:数据成员|变量(特征) + 方法|函数(行为),类是模板,并不是一个实体。
方法和函数的区别:
方法:设计层面的称谓
函数:程序运行,过程式的一种称谓
#设置构造函数(类似于包的初始化模块)
def __init__():
pass
return None #构造函数只能返回None(类型为Nonetype,属于一种特殊的数据类型)
#设置类的输入值(必须输入)
def __init__(self,name,age): #此处的self可被任意命名,但是后面的如self.name等都要换成相应的名称。
self.name = name #将类变量赋值到实例变量上
self.age = age
类变量:和模板绑定在一起的变量
实例变量: 和对象绑定在一起的变量
class Student():
# name = '' #此处不用设置变量,在python中不需要事先声明变量,变量只是名称而已。
# age = 18
def __init__(self,name,age):
self.name = name
self.age = age
def out(self):
print(self.name + str(self.age))
实例和类其实是两个客体,实例只关心self.name,而类中是否命名了name并不重要。只要赋值了self.name,实例的name就存在了,并不关心类中是否有name这个变量。
class Student():
name = 'qiyue'
age = 18
def __init__(self,name,age):
name = name #如果此处变为name = name
age = age
def out(self):
print(self.name + str(self.age))
student = Student('xzh','18')
student.out()
print(student.name)
查看对象下的所有变量(以字典的形式)
print(student.__dict__) #产看对象下的全部变量
# 当输出.name时,如果在对象下没有赋值,则系统会在类变量(类,父类)中寻找,如果类变量中也没有就会报错。
print(student.name)
#实例方法
def out(self): #必须添加self
print(self.name + str(self.age))
self本质上就是实例,例如:self.name 本质上就是 student1.name(self只是一个抽象概念指代具体的实体)
类的思维导图构造函数是用来做初始化的,而实例函数用来规定类的行为。
class Student():
name = 'qiyue'
age = 18
def __init__(self,name1,age):
self.name = name1
self.age = age
print(name)
#此时会报错,因为在类内,编译器不会调用__dict__函数查找name。只会在类外时才会调用。
#实例方法中访问类变量
使用:类名.变量名(Student.name)
使用:self.__class__.name (获取实例的类的姓名)
类方法:用于类上的基本操作
@classmethod #装饰器
def plus_num(cls): #此时的cls是类相当于(self.__class__)
cls.name = ' ' #类中的变量name
调用类方法尽量使用类进行调用,如:Student.plus_num()
静态方法:和类方法类似,只是没有显示的把类传递进来
@staticmethod
def add(x,y):
pass
成员可见性:
某些时候,我们不希望所有的变量和方法都可以在类外被调用,只能在类内进行调用。
#类中的方法可以调用其他的方法
def out(self):
print(self.name + str(self.age))
self.output()
def out_name(self):
print(self.name)
有时,数据成员不都在init方法中设置,也需要在其他方法中添加,来完善我们类设计时的逻辑性。
在方法中修改数据成员的值时可以添加逻辑(如score只能在0,100之内)
成员可见性等级:
如果变量不是以双下划线命名的,等级统统都是public(可直接在类外访问)
以双下划线命名的,等级为private(不能在类外直接访问变量)
前后都添加双下划线,也可以从外部访问(大部分都时python的内置函数,最好不要这样设置)
class Student():
def __init__(self,name):
self.name = name
self.__score = 0 #设置私有变量score
#此时以下输入并没有报错
student = Student('xzh','18')
student.__score = 1 #这里其实是给实例新增加变量__score,私有的score变量根本不会在外部搜到
print(student.__score)
#第三个为私有变量,第四个为新赋值的变量(python中其实已经把私有变量的名字修改了,如果还想调用其实也是可以的,只不过要输入正确的变量名)
{'name': 'xzh', '_Student__score': 0, '__score': 1}
面向对象三大特性:继承性,封装性,多态性
继承性:避免定义重复的方法和变量
python允许多继承(一个子类可以有多个父类)
#继承的基本结构(继承父类的方法和变量)
class Pepole():
def __init__(self, name, age):
self.name = name
self.age = age
def out_name(self):
print(self.name)
class Student(Pepole):
pass
student = Student('张三','18')
student.out_name()
输出:张三
#显式调用父类的__init__函数
class Student(Pepole):
def __init__(self, school,name,age):
Pepole.__init__(self,name,age)
self.school = school
#隐式的调用父类
class Student(Pepole):
def __init__(self, school,name,age):
super(Student,self).__init__(name,age)
self.school = school
#如果子类方法和父类方法同名,python会自动使用子类的方法
为什么方法中都必须要有一个self?:方法本质上是行为,如果没有实例化,根本谈不上行为,行为是动态的,如果没有具体化根本没有具体的行为的一说。所以要使用方法,前提就是实例化。
以下的行为也是成立的
Student.out_name(student) #深入理解类和实体
开闭原则:代码对自己的扩展是开放的,对更改自身的代码是关闭的。