文章目录
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没被使用,进行实例化后才可以调用方法
-
定义:把一个对象绑定的方法修改成一个类方法
-
作用:
- 在方法中仍然可以引用类中的静态变量
- 可以不用实例化对象,就直接用类名在外部调用这个方法
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班 ['大壮']
- s如果找不到
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系列)