- 食用说明:本笔记适用于有一定编程基础的伙伴们。希望有助于各位!
类
- 类的运用很常见:在大部分情况下,对一些特有的对象,可以使用特定的类来指向它:
class Person:name = 'unknown'age = -1sex = 0partner = Nonedef __init__(self, name, age, sex, partner):self.name = nameself.age = ageself.sex = sexself.partner = partnerdef __log(self):print(self.name, self.age, self.sex, self.partner)def greet(self):print(f"hello, {self.name}")self.__log()p1 = Person('Polaris', 18, 1, None)
p2 = Person('PolarisX', 19, 1, p1)
p2.partner.greet()
- 上处代码是一个比较完整的定义和实现
- __init__方法是实例化方法,其中self是python关键字,用于指向Person类实例,类似JS中的this
- __log方法是一个私有方法,通过双下划线定义私有方法和私有变量,当然也可以通过单下划线定义保护成员和保护方法,具体如下:
class Person:_id = -1name = 'unknown'age = -1sex = 0partner = Nonedef __init__(self, name, age, sex, partner):self._id = random.randint(0, 10000)self.name = nameself.age = ageself.sex = sexself.partner = partnerdef __log(self):print(self.name, self.age, self.sex, self.partner)def greet(self):print(f"hello, {self.name}")self.__log()def _getID(self):return self._idclass Teacher(Person):__tid = -1def __init__(self, name, age, sex, partner):super().__init__(name, age, sex, partner)self.__tid = random.randint(0, 10000)# 打印ID和TIDprint(super()._getID(), self.__tid)class Driver(Person):__did = -1def __init__(self, name, age, sex, partner):super().__init__(name, age, sex, partner)self.__did = random.randint(0, 10000)# 打印ID和TIDprint(super()._getID(), self.__did)t1 = Teacher('Polaris', 18, 1, None)
d1 = Driver('PolarisX', 20, 1, None)
- 很显然私有方法和保护方法,均无法使用,但保护方法可以通过继承给子类使用
- 继承类可以是多个,使用逗号隔开,优先会使用第一继承位的方法和成员,以防止继承多个类时的冲突
魔术方法
- python内置了许多魔术方法,先说说str魔术方法
class Teacher(Person):__tid = -1def __init__(self, name, age, sex, partner):super().__init__(name, age, sex, partner)self.__tid = random.randint(0, 10000)# 打印ID和TID# print(super()._getID(), self.__tid)def __str__(self):return f"Teacher(name={self.name}, age={self.age}, sex={self.sex}, partner={self.partner})"print(Person('Polaris', 18, 1, None))
print(Teacher('Polaris', 18, 1, None))>>> <__main__.Person object at 0x10291f050>
>>> Teacher(name=Polaris, age=18, sex=1, partner=None)
- 上面的代码返回的结果是不一样的,如果我们不设置str魔术方法,返回的是对象的内存地址,而我们定义了方法后,则会按照我们定义的格式返回
- 下面我们在说说重构类比较符,具体如下:
# 重定义小于def __lt__(self, other):return self.age < other.age# 重定义等于def __eq__(self, other):return self.age == other.age# 重定义小于等于def __le__(self, other):return self.age <= other.aget1 = Teacher('Polaris', 22, 1, None)t2 = Teacher('PolarisX', 22, 1, None)print(t1 > t2)print(t1 == t2)print(t1 <= t2)>>> False
>>> True
>>> True
- 上处代码,对比较符号进行了重构
类方法的复写
有些情况下,类的方法可能继承自父类,但父类的方法又不能满足新类的需求,我们可以实现复写:
class Phone2(Phone):def call_by_5g(self):if super()._check_5g():print('phone2 call by 5g')else:print('phone2 call by 4g') phone2 = Phone2(True)
phone2.call_by_5g()>>> phone2 call by 5g
- 上述代码中,对call_by_5g实现了复写
类型注解
类型注解和TS的类似,具体如下:
num1: int = 1num2: float = 1.2str1: str = 'hello'bool1: bool = Truelist1: list[int, float] = [1, 2, 3]tuple1: tuple[int, bool] = (1, True)dict1: dict[str, int | str | bool] = {'name': 1, 'age': 18, 'tel': '123456789X', 'is_married': True}set1: set[int] = {1, 2, 3}num3 = 1 # type: intnum4 = 1.2 # type: floatstr2 = 'hello' # type: strbool2 = True # type: boollist2 = [1, 2, 3] # type: list[int, float]tuple2 = (1, True) # type: tuple[int, bool]dict2 = {'name': 1, 'age': 18, 'tel': '123456789X', 'is_married': True} # type: dict[str, int | str | bool]set2 = {1, 2, 3} # type: set[int]p1 = Person('Pole', 18, '123456789X', True) # type: Person
- python对类型实现两种注解方式,第一种‘:’注解,第二种注释注解
- 即使用户不按照类型注解来传递值,也不会报错,但不推荐虚假注解
from typing import Union dict3: dict[str, Union[bool, str]] = {'name': 'p1'}
- 有些时候我们可能会有多个类型变量,此时使用Union可以很好的解决联合类型的问题
多态
class Person:def speak(self):passclass Teacher(Person):def speak(self):print('Teacher speak')class Driver(Person):def speak(self):print('Driver speak')def speakSth(p: Person):p.speak()p1 = Person()t1 = Teacher()d1 = Driver()speakSth(p1)speakSth(t1)speakSth(d1)>>> Teacher speak
>>> Driver speak
- 上述代码是一个简单的多态应用,常用于继承方法的不同实现
- 其中一个类中的方法无具体实现,则这就是抽象类