1.初识
1.面向过程编程vs函数式编程vs面向对象编程
s1 = 'fdskljfsda'
count = 1
for i in s1:
count += 1
l1 = [1,2,3,4,5]
count = 1
for i in l1:
count += 1
def my_len(a):
count = 1
for i in a:
count += 1
提高代码的可读性,减少了代码的重复性....
上面统称为面向过程式编程.
面向过程式编程:
好处: 出色的完成你之前布置的所有的需求.
坏处: 但凡更改或者增加一条需求,可能整个项目都随之改变.
2.面向对象的结构
# 1. 类是相似功能的集合体.
# 2. 类 你要站在上帝的角度去考虑问题.
# 类: 具有相似功能和特性的一类事物.
# 对象:类的具体体现.
# 一定要有宏观的概念,区分类与对象.
# 类的第二个优点: 你要站在上帝的角度去考虑,类一个公共模板,对象是从这个公共的模板产出的.
# 结构上分析:
class Student:
daily = '学习'
examination = '考试'
def work(self):
print('每天要上课')
def homework(self):
print('家庭作业')
# Human 类名要具有描述性,类名首字母大写,类名不宜用_
3.从类名的角度使用类
# class Student:
# """
# 此类是构建学生类
# """
#
# daily = '学习'
# examination = '考试'
#
#
# def work(self):
# print('每天要上课')
#
# def homework(self):
# print('家庭作业')
# 类名的角度调用类中的属性.
# 1. 查看类中的所有的内容. 类名.__dict__只用于获取类中的全部.
# print(Student.__dict__)
# print(Student.__dict__['daily'])
# 2. 万能的 .点.
# print(Student.daily) # 查
# Student.cloth = '校服' # 增
# print(Student.__dict__)
# Student.examination = '不考试!' # 改
# print(Student.examination)
# del Student.daily # 删
# print(Student.__dict__)
# 一般类中的属性都是通过类名.的方式去操控的.
# 类名的角度调用类中的方法.(一般类中的方法(除去类方法,静态方法外)不通过类名调用)
# Student.work(5565) # 工作中不用类名调用
4.实例化一个对象
实例化对象发生了三件事
# 1. 在内存中创建一个对象空间.
# 2. 自动执行__init__方法,并且将对象空间传给self参数.
# 3. 执行__init__方法里面的代码,给对象空间封装其属性.
对象调用对象的属性
# obj = Student()
# print(obj)
# 对象查看全部属性
# print(obj.__dict__)
# 对象可以操作对象空间的属性 万能的点
# obj = Student()
# # obj.age = '29' # 增
# # del obj.n # 删
# # obj.sex = '女'# 改
# print(obj.n) # 查
# print(obj.__dict__)
对象调用类中的属性
# 对象查看类中的属性.
# mc_sq = Student('骚强',18,'高端会所')
# # print(mc_sq.daily)
# mc_sq.daily = '骚麦'
# print(mc_sq.daily)
# print(mc_sq.__dict__)
对象调用类中的方法
# 对象调用类中的方法
liye = Student('小黑',21,'洗头')
# print(liye.__dict__)
# liye.work()
liye.work('绿油油')
print(liye.__dict__)
-
什么是self?
# self 就是类中方法的第一个位置参数, # 如果通过对象执行此方法,解释器就自动的将此对象空间当做实参传给self. # 约定俗称: 类中的方法第一个参数一般都设置成self.
2.从空间角度研究类
1.对象操作对象属性
2.类名操作属性
3.类对象指针
4.对象取值顺序
5.类名取值顺序
class A:
address = '美丽富饶的沙河'
def __init__(self, name):
self.name = name
def func(self):
if self.name == 'dsb':
self.skins = '吉利服'
def func1(self):
print(self.__dict__)
A.aaa = '易水寒'
# obj = A('dsb')
# # 类外面可以给对象封装属性
# # respons = input('太白帅不帅!')
# # if respons == '帅':
# # obj.weapon = 'AWM'
# # print(obj.__dict__)
#
# # 类内部封装属性
# obj.func()
# print(obj.__dict__)
# A.teamp = '39.5'
# print(A.__dict__)
# obj = A('dsb')
# # A.func1(111)
# A.func1(obj)
# print(A.__dict__)
class Person:
mind = '有思想'
language = '会使用语言'
def __init__(self, name, age):
self.name = name
self.age = age
def work(self):
print('人类一般都需要工作')
p1 = Person('dsb', 21)
del p1.mind # 报错
# print(p1.mind)
# p1.mind = '无脑'
# print(p1.mind)
# print(Person.mind)
# 对象如果查询一个属性: 对象空间 ----> 类空间 ----> 父类空间 --->
# 类查询一个属性: 类空间 ----> 父类空间 ---->
# 单向不可逆
# 对象与对象之间原则上互相独立(除去组合这种特殊的关系之外).
3.类与类的关系
1.依赖关系: 将一个类名或者类的对象传给另一个类的方法中.
class A:
pass
class B:
pass
# 1.依赖关系(主从关系)
# 大象进冰箱
class Elephant:
def __init__(self, name):
self.name = name
def open(self, ref1):
# print(ref1)
print(f'{self.name}默念三声: 芝麻开门')
ref1.open_door()
def close(self):
print('大象默念三声:芝麻关门')
class Refrigerator:
def __init__(self, name):
self.name = name
def open_door(self):
print(f'{self.name}冰箱门被打开了....')
def close_door(self):
print('冰箱门被关上了....')
# ele = Elephant('琪琪')
# ele1 = Elephant('安安')
# ref = Refrigerator('美菱')
# ele.open(ref)
# ele1.open(ref)
# 依赖关系: 将一个类的类名或者对象传给另一个类的方法中.
# 实现两个:
# 大象执行open方法:
# 显示: '哪个大象 大象默念三声: 芝麻开门'
# 显示: '哪个冰箱门 冰箱门被打开了....'
# 关门的流程也需要完成.
2.组合关系(关联组合聚合)
# 组合:(聚合,组合,关联)
# class Boy:
#
# def __init__(self, name):
# self.name = name
#
# def meet(self, girl_friend=None):
#
# self.girl_friend = girl_friend # wu对象空间 : girl_friend : object对象
#
# def have_diner(self): # self = wu这个对象空间
#
# if self.girl_friend:
# print(f'{self.name}请年龄为:{self.girl_friend.age},姓名为{self.girl_friend.name}一起吃六块钱的麻辣烫')
# self.girl_friend.shopping(self) # (self = wu对象空间)
# else:
# print('单身狗,吃什么吃')
#
#
#
# class Girl:
#
# def __init__(self, name, age):
# self.name = name
# self.age = age
#
# def shopping(self,boy_friend):
# print(f'{boy_friend.name},{self.name}一起去购物!')
#
# wu = Boy('吴超')
# # wu.have_diner()
# # flower = Girl('如花', 48)
# # wu.meet('如花')
# flower = Girl('如花', 48)
# # 组合: 将一个类的对象封装成另一个类的对象的属性.
# wu.meet(flower)
#
# wu.have_diner()
3.继承关系
什么是继承
专业角度: B 继承 A类, B就叫做A的子类,派生类, A叫做B的父类,基类,超类. B类以及B类的对象使用A类的所有的属性以及方法.
字面意思: 继承就是继承父母所有的资产.
继承的优点.
- 节省代码.
- 增强的耦合性.
- 代码规范化.
1.单继承
# class Animal:
# def __init__(self, name, age, sex):
# self.name = name
# self.age = age
# self.sex = sex
#
# class Person(Animal):
# pass
#
# class Dog(Animal):
# pass
#
# class Cat(Animal):
# pass
# Person Dog Cat : 子类,派生类
# Animal: 父类, 基类, 超类
1.从类名执行父类的属性.print(Person.__dict__) print(Person.live) Person.eat(55)
2.从对象执行父类的一切.实例化对象一定一定会执行三件事. 一定会执行__init__
注意: 子类以及子类对象只能调用父类的属性以及方法,不能操作(增删改).
子类重写父类的方法:子类会将父类的方法覆盖了
对象查找顺序先从对象空间找名字, 子类找名字, 父类找名字.
# class Animal:
#
# live = '有生命的'
#
# def __init__(self, name, age, sex):
# self.name = name
# self.age = age
# self.sex = sex
#
# def eat(self):
# print(f'self----> {self}')
# print('动物都需要进食')
#
#
# class Person(Animal):
#
# def __init__(self,name, age, sex, hobby):
# # 方法一:
# Animal.__init__(self, name, age, sex)
# # 方法二:
# # super(Person, self).__init__(name, age, sex)
# # super().__init__(name, age, sex)
# self.hobby = hobby
#
# def eat(self):
# print('人类需要进食')
# super().eat()
#
#
# p1 = Person('怼怼哥', 23, '不详','吹牛逼')
# # print(p1.__dict__)
# p1.eat()
2.多继承
面向对象:
python2.2之前:都是经典类,
python2.2直至python2.7之间存在两种类型: 经典类,新式类.
经典类: 基类不继承object,查询规则 依靠:深度优先的原则.
新式类: 基类必须继承object,查询规则: mro算法.(A.mro())
# mro(Child(Base1,Base2)) = [ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] )
# mro(Foo(H,G)) = [Foo] + merge(mro(H), mro(G),[H,G])
# 表头:
# 列表的第一个元素
#
# 表尾:
# 列表中表头以外的元素集合(可以为空)
# 表头,表尾
# [A,B,C] : 表头: A 表尾: [B,C]
# [A] : 表头: A 表尾: []
'''
class O:
pass
class D(O):
pass
class E(O):
pass
class F(O):
pass
class B(D,E):
pass
class C(E,F):
pass
class A(B,C):
pass
# a = A()
# a.func()
'''
'''
mro(A) = mro(A(B,C))
= [A] + merge(mro(B), mro(C), [B,C])
mro(B) = mro(B(D,E))
= [B] + merge(mro(D), mro(E), [D,E])
= [B] + merge([D,O], [E,O], [D,E])
= [B,D] + merge([O], [E,O], [E])
= [B,D,E,O]
mro(C) = mro(C(E,F))
= [C] + merge(mro(E), mro(F),[E,F])
= [C] + merge([E,O],[F,O],[E,F])
= [C,E] + merge([O],[F,O],[F])
= [C,E,F,O]
mro(A) = mro(A(B,C))
= [A] + merge([B,D,E,O], [C,E,F,O], [B,C])
= [A,B] + merge([D,E,O], [C,E,F,O], [C])
= [A,B,D] + merge([E,O], [C,E,F,O], [C])
= [A,B,D,C] + merge([E,O], [E,F,O])
= [A,B,D,C,E] + merge([O], [F,O])
= [A,B,D,C,E,F,O]
python3x 只有新式类.
面向对象三大特性: 继承封装多态.
封装:
将一些东西内容封装到一个地方,你还可以取出来.
类设置静态属性, 设置一些方法,
对象.对象可以在其对象空间中封装一些属性.
多态:
一个事物产生多种形态. 水: 气态液态固态.
python中 默认支持多态.
python中 定义变量不用规定变量的类型.
鸭子类型:
python中: 你看起来像鸭子,那么你就是鸭子.
A,B两个类,没有任何关系,独立两个,但是里面的功能相似,所以python一般会将类似于A,B两个类
里面的相似的功能让其命名相同.
1. A,B虽然无关系,但是很默契的制定了一个规范.让你使用起来更方便.
类的约束.
类的约束有两种解决方式:
# 1. 在父类建立一种约束.
# 2. 模拟抽象类(指定一种规范)的概念,建立一种约束.
# 第一种解决方式:
#
# class Payment:
#
# def pay(self,money): # 约定俗称定义一种规范,子类要定义pay方法.
# raise Exception('子类必须定义此方法')
#
#
# class QQpay(Payment):
#
# def pay(self, money):
# print(f'利用qq支付了{money}')
#
#
# class Alipay(Payment):
#
# def pay(self, money):
# print(f'利用支付宝支付了{money}')
#
# # class Wechatpay(Payment):
# # def pay(self,money):
# # print(f'利用微信支付了{money}')
#
# class Wechatpay(Payment):
# def fuqian(self,money):
# print(f'利用微信支付了{money}')
#
# # 支付功能 规划一下
#
# def pay(obj,money,choice): # 归一化设计
# obj.pay(money)
#
# choice = input('qq,weixin,zhifubao')
# obj3 = Wechatpay()
# pay(obj3,300)
# obj3.fuqian(300)
# # print(11)
# raise TypeError('代码格式错误')
# print(222)
# 第一种约束: 在父类定义一个pay方法,主动抛出异常,如果子类没有定义pay方法,并且沿用了父类的pay方法
# 即会报错. python推荐的一种约束方式.
# 第二种:
# from abc import ABCMeta,abstractmethod
#
# class Payment(metaclass=ABCMeta):
# # 抽象类 接口类 规范和约束 metaclass指定的是一个元类
# @abstractmethod
# def pay(self, money):
# pass # 抽象方法
#
#
# class QQpay(Payment):
#
# def pay(self, money):
# print(f'利用qq支付了{money}')
#
#
# class Alipay(Payment):
#
# def pay(self, money):
# print(f'利用支付宝支付了{money}')
#
# # class Wechatpay(Payment):
# # def pay(self,money):
# # print(f'利用微信支付了{money}')
#
# class Wechatpay(Payment):
# def fuqian(self,money):
# print(f'利用微信支付了{money}')
#
# # def pay(self,money):
# # pass
#
#
# obj3 = Wechatpay()
# 利用抽象类的概念: 基类如上设置,子类如果没有定义pay方法,在实例化对象时就会报错.
super的深入理解.
class A:
def f1(self):
print('in A')
class Foo(A):
def f1(self):
super().f1()
print('in Foo')
class Bar(A):
def f1(self): # self = obj
print('in Bar')
class Info(Foo,Bar):
def f1(self): # self = obj
super(Foo,self).f1()
print('in Info f1')
obj = Info() # [Info, Foo, Bar, A]
obj.f1()
# super() 严格意义并不是执行父类的方法.
# 单继承: super() 肯定是执行父类的方法.
# 多继承: super(S,self) 严格按照self从属于的类的mro的执行顺序,执行 S类的下一位.
类的私有属性
类中的私有成员: 私有类的静态属性, 私有对象属性,私有方法
类的公有静态属性
- 对于类的公有静态属性,类的外部,类的内部,派生类都可以访问.
# class B:
# school_name = '老男孩教育'
#
#
# class A(B):
#
# class_name = 'python23'
#
# def func(self):
# print(self.class_name)
#
# obj = A()
# print(obj.class_name)
# obj.func()
# print(obj.school_name)
类的私有静态属性
# class B:
# school_name = '老男孩教育'
# __consc_edu = '良心教育'
#
# class A(B):
#
# class_name = 'python23'
# __girlnum = '1个'
#
# def func(self):
# # print(self.class_name)
# # print(self.__girlnum)
# print(self.__consc_edu)
# obj = A()
# 私有静态属性: 类外部不能访问
# print(obj.__girlnum)
# print(A.__girlnum)
# 私有静态属性: 类内部可以访问
# obj.func() # 派生类不可访问
对象的私有属性
# 2. 对象的私有属性
# class B:
# school_name = '老男孩教育'
# __consc_edu = '良心教育'
#
# def __init__(self, weight):
# self.__weight = weight
# class A(B):
#
# def __init__(self, name, age, weight):
# super().__init__(weight)
# self.name = name
# self.__age = age
#
# def func(self):
# # print(self.__age) # 类的内部可以使用
# print(self.__weight) # 派生类中也不可访问
# obj = A('马倩',18, 180)
# # print(obj.__age) # 类的外部不能访问
# obj.func()
# 如果想设定一些私有的或者是不想让类外面用到,密码,加密方式,等设置成私有成员.
# 拓展: 私有成员除了在类内部,当真访问不到么?
#
# class A:
# __girlnum = '1个'
#
# print(A.__dict__)
# python中所有的私有成员: 就是在私有成员前面加上 _类名而已.
# print(A._A__girlnum) # 千万不要这么去访问!!!
类方法
class A:
num = 1
def func(self):
print('实例方法')
@classmethod # 类方法: 由类名直接调用的方法,他会自动的将类名传给cls
def a_func(cls):
# print(f'cls---> {cls}')
# print(cls.num)
# o = cls()
# print(o)
# print('这是类方法')
print(cls)
# obj = A()
# obj.func()
# A.func(obj)
# print(A)
# A.a_func()
# obj.a_func() # 对象也可以调用类方法,但是会自动将其从属于的类名传给cls
静态方法
不依赖于类,也不依赖于对象,他就是一个普通的函数放置于类中是结构更加清晰与合理.
# class A:
#
#
# def func(self):
# print(111)
# @staticmethod
# def static_func(a,b,c):
# print(f'{a}{b}{c}静态方法')
#
#
# def static_func(a,b,c):
# print(f'{a}{b}{c}静态方法')
#
# # A.static_func()
# obj = A()
# obj.static_func(1,2,3)
伪装属性
伪装成属性,虽然在代码级别没有提升,但是看起来更合理.
class Foo:
def __init__(self,name):
self.name = name
@property#后面两种方法都必须基于这个
def aaa(self):
print('get的时候运行我啊')
@aaa.setter
def aaa(self,v):
print('修改的时候执行我')
@aaa.deleter
def aaa(self):
print('删除的时候执行我')
obj = Foo('alex')
# print(obj.name)
# obj.name = 'dsb'
# del obj.name
# print(obj.name)
# obj.aaa
# obj.aaa = '太白'
# print(Foo.aaa)
# del obj.aaa
# 设置属性的另外一种写法:
# class Foo:
#
# def get_AAA(self):
# print('get的时候运行我啊')
#
# def set_AAA(self,value):
# print('set的时候运行我啊')
#
# def delete_AAA(self):
# print('delete的时候运行我啊')
#
#
# bbb = property(get_AAA,set_AAA,delete_AAA) #内置property三个参数与get,set,delete一一对应
#
# f1=Foo()
# f1.bbb
# f1.bbb='aaa'
# del f1.bbb
对象之间的关系
isinstance(基类或派生的实例化)
# 对象与类之间的关系
# isinstance(obj,N): 判断 obj对象 是由N类(N的派生类)实例化的对象 返回 True.
# print(isinstance(obj, A))
issubclass(子孙)
# issubclass(M,N) 判断是M类是N类的子孙.
# print(issubclass(C, B))
# print(issubclass(C, A))
type(判断属于哪个类)
from collections import Iterable
from collections import Iterator
# s1 = 'seewfsdkfl' # class str(Iterable) Iterable
# l1 = [1, 2, 3]
# print(type(s1)) # 判断的是对象从属于哪个类
# print(type(l1))
# print("__iter__" in dir(s1))
# print(isinstance(s1, Iterable))
#判断是否是可迭代对象
# type 到底是什么?
# type 元类 python中一切皆对象 , 一个类也是一个对象.
# 么这个(类)对象肯定是由类实例化出来的.
# python中你创建的所有类,以及大部分list str等等这些类,都是从type元类实例化得来的.
## python中继承object类都是新式类.
# object 也是由type元类实例化得来的.
异常处理(try)
单分支
# 单分支
# try:
# l1 = [1,2,3]
# print(l1[100])
#
# dic = {1: 2,'a': 'b'}
# print(dic[3])
#
# num = input('请输入序号')
# int(num)
#
# except IndexError as e:
# # print('处理了索引错误')
# print(e)
#
# print(111)
# print(222)
多分支
普通多分支
# try:
# # l1 = [1,2,3]
# # print(l1[100])
# #
# # dic = {1: 2,'a': 'b'}
# # print(dic[3])
#
# num = input('请输入序号')
# int(num)
#
# except IndexError as e:
# print('处理了索引错误')
# except KeyError as e:
# print('没有此键')
# except ValueError as e:
# print('出现了转化错误')
#
# print(111)
# print(222)
# 及时解决异常,避免程序中断.
程序的分流
# 程序的分流.
dic = {
1: 111,
2: 333,
3: 555,
}
# while 1:
# try:
# num = input('请输入序号')
# int(num)
# print(dic[int(num)])
#
# except KeyError as e:
# print('选项超出范围,请重新输入')
# except ValueError as e:
# print('请输入数字')
# print(111)
# print(222)
万能异常
# 万能异常
# try:
# num = input('请输入序号')
# int(num)
# print(dic[int(num)])
#
# except Exception as e:
# print(e)
# print(111)
# 什么时候用万能异常,什么时候用多分支?
#如果你只是想把这个异常处理掉,让程序继续执行. 万能异常.
# 如果出现了异常,你是想根据不同的异常执行不同的逻辑流程,你要采取多分支.
万能异常加多分支
# dic = {
# 1: 111,
# 2: 333,
# 3: 555,
# }
#
#
# while 1:
# try:
# num = input('请输入序号')
# int(num)
# print(dic[int(num)])
#
# except KeyError as e:
# print('选项超出范围,请重新输入')
# except ValueError as e:
# print('请输入数字')
# except Exception:
# pass
其他处理(finally)
# 异常处理其他成员
# try:
# num = input('请输入序号')
# int(num)
# print(dic[int(num)])
#
# except KeyError as e:
#
# print('选项超出范围,请重新输入')
# except Exception:
# pass
# # else: # 如果上面无异常执行else语句,否则不执行else语句.
# # print(666)
#
# finally: # 在整个程序终止之前,执行finally
# print('执行finally')
#证明方法
try:
s1 = 'a'
s2 = int(s1)
finally:
exit()#会在报错之前终止程序
函数与方法
# len()
# print()
# zip()
# str.count()
# str.split()
#
# def func():
# pass
#
#
# class A:
#
# def func(self):
# pass
# 1 通过函数名可以大致判断
# print(func) # <function func at 0x00000000005D1EA0>
# obj = A()
# print(obj.func) # <bound method A.func of <__main__.A object at 0x0000000001DE1CF8>>
# 2. 通过types模块去验证
from types import FunctionType
from types import MethodType
def func():
pass
class A:
def func(self):
pass
@staticmethod
def f():
pass
# print(isinstance(func, FunctionType))
# print(isinstance(func, MethodType))
# 类名调用func 就是一个函数
# print(isinstance(A.func, FunctionType))
# print(isinstance(A.func, MethodType))
# obj = A()
# 对象调用func 就是一个方法
# print(isinstance(obj.func, FunctionType))
# print(isinstance(obj.func, MethodType))
# 对于静态方法的研究
# print(isinstance(A.f, FunctionType))
# print(isinstance(A.f, MethodType))
# obj = A()
# # 对象调用func
# print(isinstance(obj.f, FunctionType))
# print(isinstance(obj.f, MethodType))
# 函数与方法
# 函数: 全都是显性传参
# 方法: 存在隐性传参
反射
# 从实例的角度去研究反射
# class A:
#
# static_field = '静态属性'
#
# def __init__(self, name, age):
# self.name = name
# self.age = age
#
# def func(self):
# print('in A func')
#
#
# obj = A('MC骚Q', 18)
# print(obj.name)
# #
# print(hasattr(obj,'name')) # ***
# print(getattr(obj,'name1',None)) ***
# setattr(obj,'hobby', '玩') *
# print(getattr(obj,'hobby'))
# print(obj.hobby)
# delattr(obj,'name') *
# print(hasattr(obj,'name'))
# if hasattr(obj, 'static_field'):
# print(getattr(obj,'static_field'))
#
# if hasattr(obj, 'func'):
# # print(getattr(obj,'func'))
# getattr(obj,'func')()
# 从类的角度研究反射
#
# class A:
#
# static_field = '静态属性'
#
# def __init__(self, name, age):
# self.name = name
# self.age = age
#
# def func(self):
# print(self)
# print(self.name)
# print('in A func')
#
# print(hasattr(A,'static_field'))
# print(getattr(A,'static_field'))
# obj = A('大表哥', 18)
# # print(getattr(A, 'func'))
# getattr(A,'func')(obj)
# 从当前脚本研究反射
# def func1():
# print('in func1')
#
# def func2():
# print('in func2')
# def func3():
# print('in func3')
# l1 = [func1, func2, func3]
# l1 = [f'func{i}' for i in range(1,4)]
# class B:
# static = 'B类'
import sys
# print(sys.modules)
this_modules = sys.modules[__name__] # 获取当前脚本这个对象
# print(this_modules)
# print(getattr(this_modules,'func1'))
# getattr(this_modules,'func1')()
# cls = getattr(this_modules,'B')
# obj = cls()
# print(obj.static)
# l1 = [f'func{i}' for i in range(1,4)]
# for i in l1:
# getattr(this_modules, i)()
#
# def func1():
# print('in func1')
#
# func1()
#
# def func2():
# print('in func2')
# 在其他模块研究反射
# import other_modules as om
# # om.test()
# getattr(om, 'test')()
# class Auth:
#
# function_list = [('login','请登录'), ('register','请注册'), ('exit', '退出')]
#
# def login(self):
# print('登录函数')
#
#
# def register(self):
# print('注册函数')
#
#
# def exit(self):
# print('退出...')
#
#
# while 1:
# obj = Auth()
# for num,option in enumerate(obj.function_list,1):
# print(num,option[1])
# choice_num = input('请输入选择:').strip()
# if hasattr(obj,func_name):
# getattr(obj,func_name)()
双下方法
# class A:
#
# def __init__(self,name,age,hobby):
#
# self.name = name
# self.age = age
# self.hobby = hobby
# # print(111)
#
# def __len__(self):
# # print('触发__len__方法')
# return len(self.__dict__)
# obj = A('MC骚亚伟')
# __len__
# obj = A('MC骚亚伟',18, '抽烟') #
# ret = len(obj)
# print(ret)
# 一个对象之所以可以使用len()函数,根本原因是这个对象从输入的类中有__len__方法,
# print(ret)
# len('srtfdsf')
# str
# __hash__
# class A:
#
# pass
# hash(obj) 会调用obj这个对象的类(基类)的__hash__方法
# obj = A()
# print(hash(obj))
# object
# __str__ __repr__ ***
# class Student:
#
# def __init__(self,name,age,sex):
# self.name = name
# self.age = age
# self.sex = sex
# #
#
# def __repr__(self):
# return f'姓名:{self.name}年龄:{self.age}性别:{self.sex}'
#
# def __str__(self):
# return f'姓名:{self.name}年龄:{self.age}性别:{self.sex}666'
#
# obj = Student('小智', 18, '男')
# obj1 = Student('dj智', 18, '男')
# obj2 = Student('mc智', 18, '男')
#
# # print(str(obj))
# # print(str(obj)) # 会触发__str__
# # print(obj) # 打印输出实例会触发__str__
# # print(obj1)
# # print(obj2)
# # print('此对象为%s' %obj) # 格式化输出会触发__str__
# # print(obj) # 触发__repr__
# print('此对象是%r' %obj) # 触发__repr__
#
# # print(obj) 先触发__str__方法
# __call__方法
# class A:
# def __init__(self):
# self.a = 1
# print(111)
#
# def __call__(self, *args, **kwargs):
# print(666)
#
# obj = A()
# obj()
# class A:
# def __init__(self):
# self.a = 1
# self.b = 2
#
# def __eq__(self,obj):
# print(111)
# return True
# # if self.a == obj.a and self.b == obj.b:
# # return True
# a = A()
# b = A()
# print(a == b) # 对一个类的两个对象进行比较操作,就会触发__eq__方法
# __del__ 析构方法
# class A:
#
# def __del__(self):
# print(111)
#
# obj = A()
# del obj
# l1 = [1,2,3]
# dic = {1:2}
# del l1
# del dic # 主动删除
# # print(dic)
# print(111)
# print(222)
# __new__ 构造方法
# __new__创造并返回一个新对象.
# class A(object):
#
# def __init__(self):
# print('in __init__')
#
# def __new__(cls, *args, **kwargs):
# # print(cls) # A
# print('in __new__')
# object1 = object.__new__(cls)
# return object1
# obj = A()
# 类名() 先触发__new__ 并且将类名自动传给cls.
# print(obj)
# 单例模式
# 一个类只能实例化一个对象,无论你实例化多少次,内存中都只有一个对象.
# class A:
# pass
# obj = A()
# obj1 = A()
# obj2 = A()
# print(obj,obj1,obj2)
# 面试几乎都会让你手写一个单例模式
# 这个类的对象不是个性化的,主要是实例化对象之后去执行类中的方法.
# class A:
# __instance = None
#
# def __new__(cls, *args, **kwargs):
# if not cls.__instance:
# object1 = object.__new__(cls)
# cls.__instance = object1
# return cls.__instance
#
#
# obj = A()
# obj1 = A()
# obj2 = A()
# print(obj,obj1,obj2)
# __item__
# 对对象进行类似于字典的操作
#
# class Foo:
# def __init__(self, name):
# self.name = name
#
# def __getitem__(self, item):
# print(item)
# print('get时 执行我')
#
# def __setitem__(self, key, value):
# self.name = value
# print('set时执行我')
#
# def __delitem__(self, key):
# print(f'del obj{[key]}时,我执行')
#
# obj = Foo('御姐')
# # obj.__dict__
# # obj['name']
# # obj['name'] = '萝莉'
# # print(obj.name)
# del obj['name']
# __enter__ __exit__
# class A:
# def __init__(self,name):
# self.name = name
#
# def __enter__(self):
# print(111)
#
# def __exit__(self, exc_type, exc_val, exc_tb):
# print(222)
#
# # obj = A('mc小龙')
#
# # 对一个对象类似于进行with语句上下文管理的操作, 必须要在类中定义__enter__ __exit__
# with A('mc小龙') as obj:
# print(555)
# # print(obj.name)
# class A:
#
# def __init__(self, text):
# self.text = text
#
# def __enter__(self): # 开启上下文管理器对象时触发此方法
# self.text = self.text + '您来啦'
# return self # 将实例化的对象返回f1
#
# def __exit__(self, exc_type, exc_val, exc_tb): # 执行完上下文管理器对象f1时触发此方法
# self.text = self.text + '这就走啦'
#
# # f1 = A('大爷')
# with A('大爷') as f1:
# print(f1.text)
# print(f1.text)