类有一个空间,存储的是定义在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有合作关系
__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系列)