类
类提供了数据和功能绑定在一起的方法,创建类即创建新的对象,对象是类的实例。实例可以维护自己的状态,通过方法改变状态。有点类似于带有 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