一个模块里可以用多个类么?
如何定义一个类
class Student():
# 类变量,在python中称为数据成员
name=""
age=0
# 类方法
def print_file(self):
pass
类建议使用StudentType的方式命名,而不是像变量一样使用student_type的方式命名
类的使用
形式一:在同一个模块中使用类,直接先创建一个对象,也称实例化
# Student类实例化
variable1=Student()
# 调用类下的方法
variable1.print_file()
形式二:在另一个模块中调用类,需要先引用,再实例化
# c1是Student类所在的模块名
from c1 import Student
student=Student()
Student.print_file()
一个类继承另一个类
module1.py
modele2.py
from module1 import Parent
class Child(Parent):
pass
如何定义一个方法
类的构造函数
def __init__(self):
pass
注意构造函数的调用是自动运行的,当实例化时python会自动调用构造函数
构造函数可以显式调用么?
# 可以,但一般不这样使用,毕竟实例化时已经调用过了。
# python自动调用
student=Student()
# 显式调用
student.__init__()
带入参的的构造函数
def __init__(self,name,age):
# 初始化对象特征或进行其他行为
self.name=name
self.age=age
实例方法
def print_file(self):
pass
注意:第一个参数不一定必须命名为self,这个参数命名可自定义,但推荐使用self
方法调用时,不需要为self赋值,python将自动把对象实例赋值给self
方法的调用
方式一:类内调用方法:self.方法名()
def do_homework(self):
self.do_english_homework()
方式二:类外调用方法:对象.方法名()
student=Student()
student.do_english_homework()
类方法
@classmethod
def plus_sum(cls):
pass
第一个参数不一定必须命名为cls,这个参数命名可自定义,但推荐使用cls。
方法调用时,不需要为cls赋值,python将自动把对象实例赋值给cls
类方法的调用
方式一:类名.类方法名
方式二:对象.类方法名,不推荐这样使用,因为一个对象调用类方法总显得奇怪
student=Student()
student.plus_sum()
静态方法
@staticmethod
def add(x,y):
print("this is a static method")
静态方法不像其他方法一样需要self或cls参数,静态方法更像是函数。静态方法比较鸡肋,一般不是特别建议使用静态方法,不过如果你确定一个方法,它和类与对象关系都不大时,可以使用静态方法
静态方法调用
方式一:类名.静态方法名
方式二:对象.静态方法名
student=Student()
student.add()
私有方法
def __method_name():
pass
注意:当方法名前添加双下划线后,方法会声明为私有方法,但当方法名前后都添加双下划线后,将不再私有。python的内置方法常使用这种前后都添加双下划线的方式。
访问数据成员的方式
类变量的访问
方式一:在该类的实例方法内访问类变量:self.__class__.name
class Student():
name=""
age=0
def print_file(self):
print(self.__class__.name)
方式二:在该类的类方法内访问类变量:cls.类方法名
class Student():
sum=0
@classmethod
def plus_sum(cls):
cls.sum+=1
print(cls.sum)
方式三:在该类的静态方法内访问类变量:类名.类方法名
class Student():
sum=0
@staticmethod
def add(x,y):
print(Student.sum)
方式四:在该类外访问该类变量:类名.类变量名
实例变量的声明
方式一:类内声明
class Student():
def method_name():
self.name="张三"
方式二:动态声明,类内没有实例变量,在对象中动态声明
# Student类没有__score变量
student=Student()
# 动态为对象student声明变量
student.__score=-1
print(student.__score)
实例变量的访问
方式一:通过对象访问数据成员,这里的数据成员称为实例变量
# 创建对象
student=Student()
# 方位对象数据成员
print(student.name)
查看对象下的所有实例变量
# python的内置变量__dict__中存储了对象下的所有实例变量
print(student1.__dict__)
在该类的类方法和静态方法内无法访问实例变量,即如下代码将报错
class Student():
name=""
@classmethod
def plus_sum():
print(self.name)
@staticmethod
def add(x,y):
print(self.name)
私有成员
注意:当成员名前添加双下划线后,成员会声明为私有变量,但当成员名前后都添加双下划线后,将不再私有。python的内置成员变量常使用这种前后都添加双下划线的方式。
python的实现私有的方式比较low,只是将私用成员的成员名转换为“类名_私有成员名”的形式进行存储,从而当时尝试通过私有成员名访问私有成员时找不到私有成员,存储形式如下:
既然如此,那有小伙伴问:“那是不是通过 类名_私有成员名 的方式就可以访问到私有成员?”,答案是可以的,但我们不推荐这样使用。既然一个变量已经声明为私有了,我们就不应该尝试去访问它。
对象
创建对象
通过print(id(student1))可以查看对象地址
赋予对象独属的特征
student2=Student("name",age)
注意:使用对象的实例变量时,若对象未对该变量赋值,python将去寻找类中对应的类变量;若类中也未对该变量赋值,python将尝试去类的父类中寻找。
类继承
一个类继承另一个类
module1.py
class Human():
sum=0
def __init__(self,name,age):
self.name=name
self.age=age
def get_name(self):
print(self.name)
modele2.py
from module1 import Human
class Student(Human):
pass
注意:子类将继承父类的类变量,构造函数、实例变量、实例方法
student1=Student("石敢当",18)
print(student1.sum)
print(student1.name)
print(student1.age)
student1.get_name()
print(Student.sum)
子类调用父类构造函数
方式一:
from modele1 import Human
class Student(Human):
def __init__(self,school,name,age):
self.school=school
super(Student,self).__init__(name,age)
方式二:
from module1 import Human
class Student(Human):
def __init__(self,school,name,age):
self.school=school
Human.__init__(self,name,age)
注意:其实Human. init()的第一个参数不一定要传入self,而可以传入任意对象都是可以的,如:‘ ‘
以上方法虽然可行,但不推荐使用。一个类在调用实例方法真的是一种很奇怪的方式。
方法重写:子类方法允许与父类方法重名
def get_name(self):
# 调用父类方法,可选
super(Student,self).get_name()
# 子类逻辑
print("student")