4.10 python 面向对象编程(类、对象、实例、继承、多态、封装、super()、类的装饰器、反射、内置魔术方法) 学习笔记

Valencia ·
更新时间:2024-11-10
· 621 次阅读

文章目录1 类、对象/实例、实例化2 三大特性1)继承2)封装3)多态4)super方法5)类中的三个装饰器(内置函数)6)反射7)一些内置的魔术方法3 补充1)内置数据结构2)非(python)内置数据结构3)抽象类实例 1 类、对象/实例、实例化

类有一个空间,存储的是定义在class中的所有名字

每一个类又拥有自己的空间,通过对象名.__dict__就可以查看这个对象的属性和值

修改列表/字典中的某个值,或者是对象的某一个属性,都不会影响这个对象/字典/列表所在的内存空间

类实例化所经历的步骤

类名 () 之后首先会开辟一块内存空间 调用__init__把空间的内存地址作为self参数传递到函数内部 所有的这个对象需要使用的属性都需要和self关联起来,进行对象初始化 执行完init中的逻辑后,self变量会自动的被返回到调用处(发生实例化的地方)

类中定义的变量是静态变量

对象中的变量只属于对象本身,每个对象有属于自己的空间来存储对象的变量

当使用对象名去调用某一属性的时候会有优先在自己的空间中寻找,找不到再去对应的类中寻找

如果自己没有就引用类,如果类也没有就报错

对于类来说,类中的变量所有的对象都是可以读取的,并且读取的是同一份变量

对象可以成为另一个对象的属性,嵌套组合

2 三大特性 1)继承

单继承

调用子类的:子类自己有的时候

调用父类的:子类自己没有的时候

调用子类和父类的的:子类父类都有,在子类中调用父类的 父类名.方法名(self)

# 子类想要调用父类的方法的同时还想执行自己的同名方法 # 猫和狗在调用eat的时候既调用自己的也调用父类的, # 在子类的方法中调用父类的方法 :父类名.方法名(self) class Animal: def __init__(self,name,food): self.name = name self.food = food self.blood = 100 self.waise = 100 def eat(self): print('%s is eating %s'%(self.name,self.food)) def drink(self): print('%s is drinking'%self.name) def sleep(self): print('%s is sleeping'%self.name) class Cat(Animal): def eat(self): self.blood += 100 Animal.eat(self) def climb_tree(self): print('%s is climbing'%self.name) self.drink() class Dog(Animal): def eat(self): self.waise += 100 Animal.eat(self) def house_keep(self): print('%s is keeping the house'%self.name) 小白 = Cat('小白','猫粮') 小黑 = Dog('小黑','狗粮') 小白.eat() # 小白 is eating 猫粮 小黑.eat() # 小黑 is eating 狗粮 print(小白.__dict__) # {'name': '小白', 'food': '猫粮', 'blood': 200, 'waise': 100} print(小黑.__dict__) # {'name': '小黑', 'food': '狗粮', 'blood': 100, 'waise': 200}

多继承

一个类有多个父类,在调用父类方法的时候,按照继承顺序,先继承的就先寻找

所有类默认继承object类,并且继承object类的都是新式类(python3都是)

子类.__base__ 查看子类所有继承的父类

一些方法

isinstance() 判断两个对象是否是同一个类(包括父类)

绑定方法和普通函数

判断方式:根据调用方式的不同进行判断,类中是函数,实例化对象中是方法

from types import FunctionType,MethodType # FunctionType : 函数 # MethodType : 方法 class A: def func(self): print('in func') print(A.func) # 函数 a = A() print(a.func) # 方法 print(isinstance(a.func,FunctionType)) # False print(isinstance(a.func,MethodType)) # True print(isinstance(A.func,FunctionType)) # True print(isinstance(A.func,MethodType)) # False

类属性

类名.__name__ # 类的名字(字符串) 类名.__doc__ # 类的文档字符串 类名.__base__ # 类的第一个父类 类名.__bases__ 类的所有父类构成的元组 类名.__dict__ 类的字典属性 类名.__module__ 类定义所在的模块 类名.__class__ 实例对应的类

进阶:多继承的继承顺序问题(项目和源码)

深度和广度

深度:多个类呈线性继承,长度为深度

在这里插入图片描述

广度:一个类所继承的所有直接父类数量是广度

在这里插入图片描述

广度优先(所有新式类):

在走到下一个继承点时,下一个点可以从广度和深度两个方向走的时候,总是先走广度,再走深度。

广度优先遵循的C3算法

如果是单继承 那么总是按照从子类->父类的顺序来计算查找顺序

如果是多继承 需要按照自己本类,父类1,父类2…的这种继承顺序

继承顺序

在这里插入图片描述

```python # 继承顺序 # A(0) = [AO] # B(A) = [BAO] # C(A) = [CAO] # D(B) = [DBAO] # E(C) = [ECAO] # F(D, E) = C3(D(B) + E(C)) # = [F] + D(B) + E(C) # F = [DBAO] + [ECAO] # FD = [BAO] + [ECAO] # FDB = [AO] + [ECAO] # FDBE = [AO] + {CAO} # FDBEC = [AO] + [AO] # FDBECA= [O] + [O] # FDBECAO ``` - **merge的规则** - 如果一个类出现在从左到右所有顺序的最左侧,并且没有在其他位置出现,那么先提出来作为继承顺序中的一个 - 一个类出现在从左到右顺序的最左侧,并没有在其他顺序中出现,那么先提出来作为继承顺序中的一个 - 如果从左到右第一个顺序中的第一个类出现在后面且不是第一个,那么不能提取,顺序向后继续找其他顺序中符合上述条件的类 - **用mro,查看继承顺序 类名.mro()**

进阶:通过继承实现类的开发规范(工作)

抽象类是一个开发规范,约束规范他的所有子类必须实现一些和他同名的方法

实现抽象类的方式

自己手动抛异常方式

raise 异常名(提示信息) # 主动抛异常

# class 父类: # def 子类必须实现的方法名(self,参数们): # raise NotImplementedError('提示信息') # class 子类(父类): # def 父类要求实现的方法(self,参数们): # print('''code''')

abc模块调用方式,约束力强

# from abc import ABCMeta,abstractmethod # class 父类(metaclass = ABCMeta): # @abstractmethod # def 子类必须实现的方法名(self,参数们):pass # class 子类(父类): # def 父类要求实现的方法(self,参数们): # print('''code''')

归一化设计

# class A: # def 同名功能(self):pass # class B: # def 同名功能(self):pass # # def 函数名(obj): # obj.同名功能() 2)封装

封装:把属性或者方法装起来

广义:把属性或者方法装起来,外面不能直接调用,要通过类名调用

狭义:把属性和方法藏起来,外面不能调用

使用私有的三种情况

no看no改 ok看no改 ok看ok改(按照定义的逻辑改) # 给一个名字前面加上了双下划綫的时候,这个名字就变成了一个私有的 # 所有的私有的内容或者名字都不能在类的外部调用,只能在类的内部使用了 class User: def __init__(self,name,passwd): self.usr = name self.__pwd = passwd # 私有的实例变量/私有的对象属性 def get_pwd(self): # 表示的是用户不能改只能看 私有 + 某个get方法实现的 return self.__pwd def change_pwd(self): # 表示用户必须调用我们自定义的修改方式来进行变量的修改 私用 + change方法实现 pass

封装的语法

私有的静态变量 class User: __Country = 'China' # 私有的静态变量 def func(self): print(User.__Country) # 在类的内部可以调用 print(User.Country) # 报错 在类的外部不能调用 print(User.__Country)# 报错 在类的外部不能调用 User().func() # 报错 私有的实例变量 import hashlib class User: def __init__(self,name,passwd): self.usr = name self.__pwd = passwd # 私有的实例变量 def __get_md5(self): # 私有的绑定方法 md5 = hashlib.md5(self.usr.encode('utf-8')) md5.update(self.__pwd.encode('utf-8')) return md5.hexdigest() def getpwd(self): return self.__get_md5() alex = User('alex','sbsbsb') print(alex.getpwd()) # d6170374823ac53f99e7647bab677b92 私有的绑定方法

私有的特点

私有能在类的内部使用

私有不能在类的外部

私有原理:使用私有加下划线后的名字不能从类的外部调用的原因 class User: __Country = 'China' # 私有的静态变量 __Role = '法师' # 私有的静态变量 def func(self): print(self.__Country) # 在类的内部使用的时候,自动的把当前这句话所在的类的名字拼在私有变量前完成变形 print(User._User__Country) # '_User__Country': 'China' print(User._User__Role) # __Role '_User__Role': '法师' User.__aaa = 'bbb' # 在类的外部根本不能定义私有的概念

私有的内容不能被子类使用

class Foo(object): def __init__(self): self.func() def func(self): print('in Foo') class Son(Foo): def func(self): print('in Son') Son() # in Son class Foo(object): def __init__(self): self.__func() def __func(self): print('in Foo') class Son(Foo): def __func(self): print('in Son') Son() # in Foo class Foo(object): def __func(self): print('in Foo') class Son(Foo): def __init__(self): self.__func() Son() # 报错

python中的数据级别

public 公有的,类内类外都能用,父类子类都能用 private 私有的,本类的类内部能用,其他地方都不能用 不支持protect 保护的,类内能用,父类子类都能用,类外不能用 3)多态

python处处是多态,一切皆对象

多态定义

多态:一个类型表现出的多种状态

# 什么是多态 : 一个类表现出的多种形态,实际上是通过继承来完成的 # 如果狗类继承动物类,猫类也继承动物类 # 那么我们就说猫的对象也是动物类型的 # 狗的对象也是动物类型的 # 在这一个例子里,动物这个类型表现出了猫和狗的形态

在JAVA情况下,一个参数必须指定类型

# def eat(动物类型 猫的对象/狗的对象,str 食物): # print('动物类型保证了猫和狗的对象都可以被传递进来')

python处处是多态,一切皆对象

如果想让两个类型的对象都可以传,那么必须让这两个类继承自同一个父类,在指定类型的时候用父类来指定

class Payment:pass class WeChat(Payment): def __init__(self,name): self.name = name def pay(self,money): dic = {'username':self.name,'money':money} # 想办法调用微信支付 url连接 把dic传过去 print('%s通过微信支付%s钱成功'%(self.name,money)) class Apple(Payment): def __init__(self,name): self.name = name def pay(self,money): dic = {'name': self.name, 'number': money} # 想办法调用苹果支付 url连接 把dic传过去 print('%s通过苹果支付%s钱成功' % (self.name, money))

鸭子模型

# 子类继承父类,我们说子类是父类类型的(猫类继承动物,我们说猫也是动物) # 在python中,一个类是不是属于某一个类型 # 不仅仅可以通过继承来完成 # 还可以是不继承,但是如果这个类满足了某些类型的特征条件 # 我们就说它长得像这个类型,那么他就是这个类型的鸭子类型 4)super方法

使用:super().方法名()

理解:

多继承中:按照mro顺序来寻找当前类的下一个类,不需要传参数,自动就帮我们寻找当前类的mro顺序的下一个类中的同名方法进行调用

class A(object): def func(self): print('A') class B(A): def func(self): super().func() print('B') class C(A): def func(self): super().func() print('C') class D(B,C): def func(self): super().func() super(D,self).func() print('D') D().func() # A, C, B, D

单继承中:super就是找父类

class User: def __init__(self,name): self.name = name class VIPUser(User): def __init__(self,name,level,strat_date,end_date): # User.__init__(self,name) super().__init__(name) # 推荐的 # super(VIPUser,self).__init__(name) self.level = level self.strat_date = strat_date self.end_date = end_date 太白 = VIPUser('太白',6,'2019-01-01','2020-01-01') print(太白.__dict__) # {'name': '太白', 'level': 6, 'strat_date': '2019-01-01', 'end_date': '2020-01-01'} 5)类中的三个装饰器(内置函数)

@property

作用:把一个方法伪装成一个属性,在调用这个方法时不需要加 () 就可以直接得到方法返回值

应用

第一个应用场景:简单的property

import time class Person: def __init__(self,name,birth): self.name = name self.birth = birth @property def age(self): # 装饰的这个方法 不能有参数 return time.localtime().tm_year - self.birth 太白 = Person('太白',1998) print(太白.age) # 22

第二个应用场景:与私有属性合作

class Goods: discount = 0.8 def __init__(self,name,origin_price): self.name = name self.__price = origin_price @property def price(self): return self.__price * self.discount apple = Goods('apple',5) print(apple.price) # 4.0

应用进阶1 setter

class Goods: discount = 0.8 def __init__(self,name,origin_price): self.name = name self.__price = origin_price @property def price(self): return self.__price * self.discount @price.setter def price(self,new_value): if isinstance(new_value,int): self.__price = new_value apple = Goods('apple',5) print(apple.price) # 调用的是被@property装饰的price, 4.0 apple.price = 10 # 调用的是被setter装饰的price print(apple.price) # 8.0

应用进阶2 deleter

class Goods: discount = 0.8 def __init__(self,name,origin_price): self.name = name self.__price = origin_price @property def price(self): return self.__price * self.discount @price.setter def price(self,new_value): if isinstance(new_value,int): self.__price = new_value @price.deleter def price(self): del self.__price apple = Goods('apple',5) print(apple.price) # 4.0 apple.price = 'ashkaksk' del apple.price # 并不能真的删除什么,只是调用对应的被@price.deleter装饰的方法而已 print(apple.price) # 报错

@classmethod

被装饰的方法会成为一个类方法

使用原因:定义了一个方法,默认传self,但这个self没被使用,进行实例化后才可以调用方法

定义:把一个对象绑定的方法修改成一个类方法

作用:

s在方法中仍然可以引用类中的静态变量 s可以不用实例化对象,就直接用类名在外部调用这个方法 class Goods: __discount = 0.8 def __init__(self): self.__price = 5 self.price = self.__price * self.__discount @classmethod # 把一个对象绑定的方法 修改成一个 类方法 def change_discount(cls,new_discount): cls.__discount = new_discount Goods.change_discount(0.6) # 类方法可以通过类名调用 apple = Goods() print(apple.price) # 3.0 apple.change_discount(0.5) # 类方法可以通过对象名调用 apple2 = Goods() print(apple2.price) # 2.5

应用:

定义了一个方法,默认传self,但这个self没被使用 并且你在这个方法里用到了当前的类名,或者你准备使用这个类的内存空间中的名字的时候 import time class Date: def __init__(self,year,month,day): self.year = year self.month = month self.day = day @classmethod def today(cls): struct_t = time.localtime() date = cls(struct_t.tm_year,struct_t.tm_mon,struct_t.tm_mday) return date date对象 = Date.today() print(date对象.year) # 2020 print(date对象.month) # 4 print(date对象.day) # 10

@staticmethod

被装饰的方法会成为一个静态方法

class User: pass @staticmethod def login(a,b): # 本身是一个普通的函数,被挪到类的内部执行,那么直接给这个函数添加@staticmethod装饰器就可以了 print('登录的逻辑',a,b) # 在函数的内部既不会用到self变量,也不会用到cls类 obj = User() User.login(1,2) # 登录的逻辑 1 2 obj.login(3,4) # 登录的逻辑 3 4

能定义到类中的内容

静态变量 是个所有的对象共享的变量 有对象\类调用 但是不能重新赋值 绑定方法 是个自带self参数的函数 由对象调用 类方法 是个自带cls参数的函数 由对象\类调用 静态方法 是个啥都不带的普通函数 由对象\类调用 property属性 是个伪装成属性的方法 由对象调用 但不加括号 class A: country = '中国' def func(self): print(self.__dict__) @classmethod def clas_func(cls): print(cls) @staticmethod def stat_func(): print('普通函数') @property def name(self): return 'wahaha' 6)反射

定义:用字符串数据类型的名字,来操作这个名字对应的函数/实例变量/绑定方法/各种方法

理解:在知道一个变量的字符串数据类型的名字,想要直接调用它,但是调用不到,此时使用反射

格式:

对象名.属性名 ==> getattr(对象名, ‘属性名’)

class Person: def __init__(self,name,age): self.name = name self.age = age alex = Person('alex',83) ret = getattr(alex,'name') print(ret) # alex

hasattr(对象名,属性名) ==> 判断属性是否在对象内能不能反射,防止getattr报错

class A: Role = '治疗' def __init__(self): self.name = 'alex' self.age = 84 def func(self): print('wahaha') return 666 a = A() print(hasattr(a,'sex')) # False print(hasattr(a,'age')) # True if hasattr(a,'age'): print(getattr(a, 'age')) # 84

callable 判断是不是可调用的(方法/函数)

print(hasattr(a,'func')) # 报错/True if hasattr(a,'func'): if callable(getattr(a,'func')): # 判断是否可调用 getattr(a,'func')() # wahaha

使用场景:

反射对象的 实例变量

class A: Role = '治疗' def __init__(self): self.name = 'alex' self.age = 84 def func(self): print('wahaha') return 666 a = A() print(getattr(a,'name')) # 反射对象的实例变量 # alex

反射类的 静态变量/绑定方法/其他方法

print(getattr(a,'func')()) # 反射对象的绑定方法, wahaha 666 print(getattr(A,'Role')) # 反射对象的静态变量, 治疗

模块中的所有变量

被导入的模块

import a # 引用模块中的任意的变量 print(getattr(a,'sww'),a.sww) getattr(a,'sww')() print(getattr(a,'lst'),a.lst) print(getattr(a,'dic'),a.dic) print(getattr(a,'we'),a.we) # 模块a class Wechat:pass class Alipay:pass def sww(): print('爽歪歪') lst = [1,2,3,4,5] dic = {'k':'v'} we = Wechat()

当前执行的py文件 ——脚本

import sys # 反射本模块中的名字 cat = '小a' dog = '小b' def pig(): print('小p') print(getattr(sys.modules['__main__'],'cat')) # 小a print(getattr(sys.modules['__main__'],'dog')) # 小b getattr(sys.modules['__main__'],'pig')() # 小p

实例 —— 归一化设计

class Payment:pass class Alipay(Payment): def __init__(self,name): self.name = name def pay(self,money): dic = {'uname':self.name,'price':money} print('%s通过支付宝支付%s钱成功'%(self.name,money)) class WeChat(Payment): def __init__(self,name): self.name = name def pay(self,money): dic = {'username':self.name,'money':money} print('%s通过微信支付%s钱成功'%(self.name,money)) class Apple(Payment): def __init__(self,name): self.name = name def pay(self,money): dic = {'name': self.name, 'number': money} print('%s通过苹果支付%s钱成功' % (self.name, money)) class QQpay: def __init__(self,name): self.name = name def pay(self,money): print('%s通过qq支付%s钱成功' % (self.name, money)) import sys def pay(name,price,kind): class_name = getattr(sys.modules['__main__'],kind) obj = class_name(name) obj.pay(price) # if kind == 'Wechat': # obj = WeChat(name) # elif kind == 'Alipay': # obj = Alipay(name) # elif kind == 'Apple': # obj = Apple(name) # obj.pay(price) pay('alex',400,'WeChat') # alex通过微信支付400钱成功 pay('alex',400,'Alipay') # alex通过支付宝支付400钱成功 pay('alex',400,'Apple') # alex通过苹果支付400钱成功 pay('alex',400,'QQpay') # alex通过qq支付400钱成功 7)一些内置的魔术方法

__call__方法 对象 () 调用这个类中的__call__方法

class A: def __call__(self, *args, **kwargs): print('-------') obj = A() print(callable(obj)) # True obj() # -------

__len__方法 len(对象) 需要实现这个类中的__len__方法

class Cls: def __init__(self,name): self.name = name self.students = [] def len(self): return len(self.students) def __len__(self): return len(self.students) py22 = Cls('py22') py22.students.append('杜相玺') py22.students.append('庄博') py22.students.append('大壮') print(py22.len()) # 3 print(len(py22)) # 3

__new__方法

实例化的时候先创建一块对象的空间,有一个指针能指向类 --> __new__方法,再调用init --> __init__

设计模式

单例模式:一个类 从头到尾 只会创建一次self的空间

两种方式:

__new__实现

class Baby: __instance = None def __new__(cls, *args, **kwargs): # 构造方法 if cls.__instance is None: cls.__instance = super().__new__(cls) return cls.__instance def __init__(self,cloth,pants): self.cloth = cloth self.pants = pants b1 = Baby('红毛衣','绿皮裤') print(b1.cloth) # 红毛衣 b2 = Baby('白衬衫','黑豹纹') print(b1.cloth) # 白衬衫 print(b2.cloth) # 白衬衫

python 通过模块导入实现

# 单例.模块 class Baby: def __init__(self,cloth,pants): self.cloth = cloth self.pants = pants baby = Baby('红上衣','绿裤子') from 单例 import Baby # 永远只占用单例模块中创建的那个内存空间

__str__方法 帮助我们在打印/展示对象的时候更直观的显示对象内容,%s str() print()

在打印一个对象的时候 调用__str__方法 在%s拼接一个对象的时候 调用__str__方法 在str一个对象的时候 调用__str__方法 class clas: def __init__(self): self.student = [] def append(self,name): self.student.append(name) def __repr__(self): return str(self.student) def __str__(self): return 'aaa' py22 = clas() py22.append('大壮') print(py22) # aaa print(str(py22)) # aaa print('我们py22班 %s'%py22) # 我们py22班 aaa

__repr__方法 是str的备胎方法,同时还和%r有合作关系

s如果找不到__str__,就调用__repr__方法 用%r进行字符串拼接 或者用repr(对象)的时候总是调用这个对象的__repr__方法 class clas: def __init__(self): self.student = [] def append(self,name): self.student.append(name) def __repr__(self): return str(self.student) # def __str__(self): # return 'aaa' py22 = clas() py22.append('大壮') print(py22) # ['大壮'] print(str(py22)) # ['大壮'] print('我们py22班 %s'%py22) # 我们py22班 ['大壮'] 3 补充 1)内置数据结构 {} key-value [] 序列 () 元组 {1, } 集合 ‘ ’ 字符串 2)非(python)内置数据结构 Queue队列:先进先出 FIFO(FIRST IN FIRST OUT) put 放数据 get 取数据 Stack栈 :后进先出 LIFO(LAST IN FIRST OUT) put 放数据 get 取数据 自定义pickle 3)抽象类实例 # 抽象类 是一个开发的规范 约束它的所有子类必须实现一些和它同名的方法 # 支付程序 # 微信支付 url连接,告诉你参数什么格式 # {'username':'用户名','money':200} # 支付宝支付 url连接,告诉你参数什么格式 # {'uname':'用户名','price':200} # 苹果支付 # class Payment: # 抽象类 # def pay(self,money): # '''只要你见到了项目中有这种类,你要知道你的子类中必须实现和pay同名的方法''' # raise NotImplementedError('请在子类中重写同名pay方法') # # class Alipay(Payment): # def __init__(self,name): # self.name = name # def pay(self,money): # dic = {'uname':self.name,'price':money} # # 想办法调用支付宝支付 url连接 把dic传过去 # print('%s通过支付宝支付%s钱成功'%(self.name,money)) # # class WeChat(Payment): # def __init__(self,name): # self.name = name # def pay(self,money): # dic = {'username':self.name,'money':money} # # 想办法调用微信支付 url连接 把dic传过去 # print('%s通过微信支付%s钱成功'%(self.name,money)) # # class Apple(Payment): # def __init__(self,name): # self.name = name # def pay(self,money): # dic = {'name': self.name, 'number': money} # # 想办法调用苹果支付 url连接 把dic传过去 # print('%s通过苹果支付%s钱成功' % (self.name, money)) # aw = WeChat('alex') # aw.pay(400) # aa = Alipay('alex') # aa.pay(400) # 归一化设计 # def pay(name,price,kind): # if kind == 'Wechat': # obj = WeChat(name) # elif kind == 'Alipay': # obj = Alipay(name) # elif kind == 'Apple': # obj = Apple(name) # obj.pay(price) # # pay('alex',400,'Wechat') # pay('alex',400,'Alipay') # pay('alex',400,'Apple') # appa = Apple('alex') # appa.fuqian(500) # 实现抽象类的另一种方式,约束力强,依赖abc模块 # from abc import ABCMeta,abstractmethod # class Payment(metaclass=ABCMeta): # @abstractmethod # def pay(self,money): # '''只要你见到了项目中有这种类,你要知道你的子类中必须实现和pay同名的方法''' # raise NotImplementedError('请在子类中重写同名pay方法') # # class Alipay(Payment): # def __init__(self,name): # self.name = name # def pay(self,money): # dic = {'uname':self.name,'price':money} # # 想办法调用支付宝支付 url连接 把dic传过去 # print('%s通过支付宝支付%s钱成功'%(self.name,money)) # # class WeChat(Payment): # def __init__(self,name): # self.name = name # def pay(self,money): # dic = {'username':self.name,'money':money} # # 想办法调用微信支付 url连接 把dic传过去 # print('%s通过微信支付%s钱成功'%(self.name,money)) # # WeChat('alex')

注:此文为个人学习笔记(old_boy系列)


作者:1_XTW



面向对象编程 反射 学习笔记 魔术 super 装饰器 继承 方法 封装 对象 学习 面向对象 多态 Python

需要 登录 后方可回复, 如果你还没有账号请 注册新账号