python知识点
魔术方法
魔术方法有init,str,lt,le,eq等等,其中__init__是构造方法,不再阐述
__str__
下面直接打印stu和str(stu)都会输出内存地址
class Student: def __init__(self, name, age): self.name = name self.age = age stu = Student("xby",20) print(stu) #<__main__.Student object at 0x000001AF57027C40> print(str(stu)) #<__main__.Student object at 0x000001AF57027C40>
但是我们一般不需要内存地址,便使用__str__方法如下
class Student: def __init__(self, name, age): self.name = name self.age = age def __str__(self): return f"Student类对象,name:{self.name},age:{self.age}" stu = Student("xby",20) print(stu) #Student类对象,name:xby,age:20 print(str(stu)) #Student类对象,name:xby,age:20
这样我们就得到了我们想要的内容
__lt__
我们可以使用这个魔术方法来判断大于或者小于
class Student: def __init__(self, name, age): self.name = name self.age = age def __lt__(self,other): return self.age < other.age stu1 = Student("xby1",20) stu2 = Student("xby2",22) print(stu1 < stu2) #True print(stu1 > stu2) #False
__le__
我们可以使用这个魔术方法来判断大于等于或者小于等于
class Student: def __init__(self, name, age): self.name = name self.age = age def __le__(self,other): return self.age <= other.age stu1 = Student("xby1",20) stu2 = Student("xby2",22) print(stu1 <= stu2) #True print(stu1 >= stu2) #False
__eq__
把符号换成==,其余同上
私有成员
私有成员的变量和方法都用__开头即可
class Phone: __current_voltage = None def __keep_single_core(self): print("CPU单核运行") phone = Phone() phone.__keep_single_core() #error print(phone.__current_voltage) #error
发现类对象调用变量和方法都会报错,那怎么调用呢?虽然类对象不能调用,但是类中的其他成员是可以访问的
class Phone: __current_voltage = 2 def __keep_single_core(self): print("CPU单核运行") def call_by_5g(self): if self.__current_voltage >= 1: print("5g_ok") else: self.__keep_single_core() print("电压不足,设置为单核模式") phone = Phone() phone.call_by_5g() #5g_ok #若__current_voltage = 0.5 -> CPU单核运行 电压不足,设置为单核模式
继承
单继承:一个子类继承一个父类
class Phone: IMEI = None producer = "xby" def call_by_4g(self): print("4g") class Phone2024(Phone): face_id = "10001" def call_by_5g(self): print("new:5g") phone = Phone2024() print(phone.producer) phone.call_by_4g() phone.call_by_5g() # xby # 4g # new:5g
多继承:一个子类继承多个父类
class A: IMEI = 12 class B: face_id = "10001" class C: name = "xby" class X(A,B,C): pass#不想再添加新的功能 x = X() print(x.IMEI,x.face_id,x.name) #12 10001 xby
注意事项:如果父类中的成员有一样的,按照括号里的顺序,从左开始依次,谁先继承,谁的优先级更高
复写:对继承的父类进行修改
class Phone: IMEI = None producer = "xby" def call_by_5g(self): print("5g") class MyPhone(Phone): producer = "XBY"#复写父类的成员属性 def call_by_5g(self):#复写父类的成员方法 print("new:5g++") phone = MyPhone() phone.call_by_5g() print(phone.producer) # new:5g++ # XBY
一旦复写,调用就默认是复写后的,那怎么使用父类之前的呢,可以调用父类成员或者使用super()调用父类成员
class Phone: IMEI = None producer = "xby" def call_by_5g(self): print("5g") class MyPhone(Phone): producer = "XBY"#复写父类的成员属性 def call_by_5g(self):#复写父类的成员方法 #方式一 print(f"父类的厂商是:{Phone.producer}") Phone.call_by_5g(self) #方式二 print(f"父类的厂商是:{super().producer}") super().call_by_5g() print("new:5g++") phone = MyPhone() phone.call_by_5g() # 父类的厂商是:xby # 5g # 父类的厂商是:xby # 5g # new:5g++
注解
变量的类型注解
import random import json #基础数据类型注解 var_1: int = 10 #类对象类型注解 class Student: pass stu:Student = Student() #基础容器类型注解 my_list: list = [1,2,3] my_tuple: tuple = (1,2,3) my_dict: dict = {"xby": 666} #容器类型详细注解 my_list: list[int] = [1,2,3] my_tuple: tuple[int,str,bool] = (1,"xby",True) my_dict: dict[str,int] = {"xby": 666} ###在注释中进行类型注解 var_2 = random.randint(1,10) #type:int var_3 = json.loads('{"name":"xxx"}') #type:dict[str,str] def func(): return 10 var_4 = func() #type:int ###类型注解标记错了,不会影响编译运行 var_5: int = "xby"
函数和方法的类型注解
#对形参类型注解 def add(x: int, y: int): return x+y #对返回值类型注解 def func(data: list) -> list: return data
介绍一下Union联合类型
from typing import Union my_list: list[Union[int,str]] = [1,2,"xby","XBY"] def func(data: Union[int,str])->Union[int,str]: pass
多态
同样的函数,传入不同的对象,得到不同的状态
用在继承关系上
class Animal: def speak(self): pass class Dog(Animal): def speak(self): print("汪汪汪") class Cat(Animal): def speak(self): print("喵喵喵") def make_noise(animal: Animal): animal.speak() dog = Dog() cat = Cat() make_noise(dog) make_noise(cat) # 汪汪汪 # 喵喵喵
用在抽象类(接口)
抽象类:含有抽象方法的类
抽象方法:方法体式空实现的(pass)
class AC: def cool(self): """cool""" pass def hot(self): """hot""" class xby_AC(AC): def cool(self): print("xby_cool") def hot(self): print("sby_hot") def make_cool(ac:AC): ac.cool() xby = xby_AC() make_cool(xby) # xby_cool
闭包
因为全局变量不安全,可以在函数嵌套条件下,内部函数使用外部函数的变量,并且外部函数返回了内部函数,这个内部函数称为闭包
既想依赖外部全局变量,又不想全局变量可以被修改
简单闭包
def outer(logo): def inner(msg): print(f"{logo}{msg}") return inner fn1 = outer("xby") # fn1的类型是函数 fn1("1") fn2 = outer("XBY") # fn2的类型是函数 fn2("1") # xby1 # XBY1
但是需要修改怎么办,使用nonlocal关键字
def outer(num1): def inner(num2): nonlocal num1 num1 += num2 print(num1) return inner fn = outer(10) fn(20) # num1 = 30 fn(20) # num1 = 50
装饰器
装饰器其实也是一种闭包,在不破坏目标函数原有的代码和功能的前提下,为目标函数增加新功能
用闭包的方式(不高级)
def outer(func): def inner(): print(1) func() print(2) return inner def sleep(): print("sleep") fn = outer(sleep) fn() # 1 # sleep # 2
使用@简洁一点
def outer(func): def inner(): print(1) func() print(2) return inner @outer def sleep(): print("sleep") sleep() # 1 # sleep # 2