- 食用说明:本笔记适用于有一定编程基础的伙伴们。希望有助于各位!
类
- 类的运用很常见:在大部分情况下,对一些特有的对象,可以使用特定的类来指向它:
class Person:
name = 'unknown'
age = -1
sex = 0
partner = None
def __init__(self, name, age, sex, partner):
self.name = name
self.age = age
self.sex = sex
self.partner = partner
def __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 = -1
name = 'unknown'
age = -1
sex = 0
partner = None
def __init__(self, name, age, sex, partner):
self._id = random.randint(0, 10000)
self.name = name
self.age = age
self.sex = sex
self.partner = partner
def __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._id
class Teacher(Person):
__tid = -1
def __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)
class Driver(Person):
__did = -1
def __init__(self, name, age, sex, partner):
super().__init__(name, age, sex, partner)
self.__did = random.randint(0, 10000)
# 打印ID和TID
print(super()._getID(), self.__did)
t1 = Teacher('Polaris', 18, 1, None)
d1 = Driver('PolarisX', 20, 1, None)
- 很显然私有方法和保护方法,均无法使用,但保护方法可以通过继承给子类使用
- 继承类可以是多个,使用逗号隔开,优先会使用第一继承位的方法和成员,以防止继承多个类时的冲突
魔术方法
- python内置了许多魔术方法,先说说str魔术方法
class Teacher(Person):
__tid = -1
def __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.age
t1 = 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 = 1
num2: float = 1.2
str1: str = 'hello'
bool1: bool = True
list1: 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: int
num4 = 1.2 # type: float
str2 = 'hello' # type: str
bool2 = True # type: bool
list2 = [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):
pass
class 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
- 上述代码是一个简单的多态应用,常用于继承方法的不同实现
- 其中一个类中的方法无具体实现,则这就是抽象类