Skip to content

类提供了数据和功能绑定在一起的方法,创建类即创建新的对象,对象是类的实例。实例可以维护自己的状态,通过方法改变状态。有点类似于带有 nonlocal 的函数,通过闭包维护内部的变量。

类的定义与实例化

python
class MyClass:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.gender = 'male'
    
    def say_hello(self):
        print(f'Hello, my name is {self.name} and I am {self.age} years old.')

    def say(self):
        self.say_hello()

类里面的 def 称之为方法,方法的第一个参数是 self,表示实例本身。

__init__ 是类的构造函数,在创建实例时自动调用。构造函数的参数需要再实例化的过程中进行传递。在构造函数中也可以对实例的属性进行初始化。

实例化类时,需要使用 类名() 的方式,在括号中传递构造函数的参数。

python
my_instance = MyClass('Alice', 25)
my_instance.say_hello()

属性与方法

实例属性、实例方法

声明在 __init__ 构造方法内并且用 self.xx 命名的方法一般成为实例的属性,该属性只有当类被实例化之后才能被访问

py
class Basic:
    def __init__(self, desc):
        # 可以通过外部传入,也可以自己定义初始化的值
        self.name = 'inital value'
        self.desc = desc

    def get_message(self):
        return f"name: {self.name}, desc: {self.desc}."

basic = Basic('this is desc')
print(basic.name, basic.desc)
print(basic.get_message())

print(Basic.name, '...') # ❌

类方法、类属性

绑定到类本身的方法以及属性,不同 self 关键字访问和声明,方法的第一个参数是类本身 cls。方法上面通常使用 @classmethod 进行装饰。

python
class Basic:
    cls_data = 'initial value'

    @classmethod
    def get_cls_data(cls):
        print(cls.cls_data)

Basic.get_cls_data()
print(Basic.cls_data)

静态方法

静态方法使用 @staticmethod 装饰器,在内部无法访问实例的属性以及方法,也不能通过 cls 访问类的属性和方法。一般用来存放一些和类逻辑相关,但是数据不想干的数据。

py
class Basic:
    name = 'cls_basic'
    def __init__(self):
        self.name = 'instance_basic'

    @staticmethod
    def get_name():
        print(Basic.name)

Basic.get_name()

计算属性

可以通过 @property 来声明计算属性,让类用于简单的计算功能,或者一些表达式的应用。

py
class Clac:
    def __init__(self, num):
        self.num = num

    @property
    def double(self):
        return self.num * 2

print(Clac(10).double) # 20

继承

python
class Base:
    def __init__(self, name):
        self.name = name
        
    def get_user_details(self):
        print(self.name)


class Child(Base):
    def __init__(self, name, age):
        super().__init__(name)
        self.age = age

    def get_user_details(self):
        super().get_user_details()
        print(self.age)

    def say_hello(self):
        print('Hello, my name is', self.name)

child = Child('John', 25)
child.get_user_details()
child.say_hello()
  • 父类有的方法,子类没有的情况下,子类实例可以直接调用,类中进行调用需要使用 super() 调用父类的方法。
  • 子类可以重写父类的方法,也可以调用父类的方法。
  • 子类可以添加新的方法,也可以重写父类(同样的方法名)的方法。
  • 子类可以添加新的属性,也可以重写父类的属性。(不推荐)

多重继承

多重继承时,如果出现相同的方法,则使用最先继承类(从左至右)

py
class Base:
    def __init__(self):
        self.name = 'Base'

    def get_name(self):
        return self.name

class Basic:
    def __init__(self):
        self.name = 'Basic'
    
    def get_name(self):
        return self.name

class Child(Base, Basic):
    def __init__(self):
        self.name = 'Child'

    def get_name(self):
        print(super().get_name())

child = Child()
child.get_name() # Base