9.1面向对象

一个模块里可以用多个类么?

可以哦

如何定义一个类

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

class Parent():
    pass

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.plus_sum()

方式二:对象.类方法名,不推荐这样使用,因为一个对象调用类方法总显得奇怪

student=Student()
student.plus_sum()

静态方法

@staticmethod
def add(x,y):
    print("this is a static method")

静态方法不像其他方法一样需要self或cls参数,静态方法更像是函数。静态方法比较鸡肋,一般不是特别建议使用静态方法,不过如果你确定一个方法,它和类与对象关系都不大时,可以使用静态方法

静态方法调用

方式一:类名.静态方法名

Student.add(1,2)

方式二:对象.静态方法名

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)

方式四:在该类外访问该类变量:类名.类变量名

print(Student.name)

实例变量的声明

方式一:类内声明

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)

私有成员

__field_name

注意:当成员名前添加双下划线后,成员会声明为私有变量,但当成员名前后都添加双下划线后,将不再私有。python的内置成员变量常使用这种前后都添加双下划线的方式。

python的实现私有的方式比较low,只是将私用成员的成员名转换为“类名_私有成员名”的形式进行存储,从而当时尝试通过私有成员名访问私有成员时找不到私有成员,存储形式如下:

_Student__score

既然如此,那有小伙伴问:“那是不是通过 类名_私有成员名 的方式就可以访问到私有成员?”,答案是可以的,但我们不推荐这样使用。既然一个变量已经声明为私有了,我们就不应该尝试去访问它。

对象

创建对象

student1=Student()

通过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")

Last updated

Was this helpful?