python金牌班第七周周末总结

面向对象前戏

1.我们在学习面相对像之前有一个推导过程如何将我们之前写的东西,从一串代码转向给对象服务。
2.实例
我们首先模拟了两个物种进行战斗的场景,然后我们发现我们都可以调用对方的数据因为我们的数据都是共享的,我们就需要将他绑定给她对应的对象然后就不会出现在这个对象外进行互相乱调用的情况。
3.代码
def Get_The_Butcher_of_the_sands(name, death_type, attack, health_point):
"""
# 首先创建荒漠屠夫的用户字典
:param name: 姓名
:param death_type:类型
:param attack: 攻击方式
:param health_point: 生命值
:return: 荒漠屠夫的字典
"""
The_Butcher_of_the_sands = { # 荒漠屠夫构建
'name': name,
'sands': death_type,
'the_tyrant_beat': attack,
'health_point': health_point
}
return The_Butcher_of_the_sands # p2 = get_The_Butcher_of_the_sands('renekton', 'soaring', 350, 3500)
# 3.让沙漠死神内瑟斯和荒漠屠夫雷克顿大战起来
def Desert_of_death_attack(Desert_of_death, The_Butcher_of_the_sands):
"""
内瑟斯打雷克顿
:param Desert_of_death:传内瑟斯数据
:param The_Butcher_of_the_sands:雷克顿数据
:return:
"""
print('即将被攻击的:%s, 当前血量 %s' % (The_Butcher_of_the_sands.get('name'),
The_Butcher_of_the_sands.get('health_point')))
The_Butcher_of_the_sands['health_point'] -= Desert_of_death['the_soul_from']
print('Desert_of_death:%s 使用 the_soul_from 攻击 The_Butcher_of_the_sands:%s ,The_Butcher_of_the_sands 掉血:%s 剩余血量:%s' %
(Desert_of_death.get('name'), The_Butcher_of_the_sands.get('name'), Desert_of_death.get('the_soul_from'),
The_Butcher_of_the_sands.get('health_point'))) def The_Butcher_of_the_sands_attack(The_Butcher_of_the_sands, Desert_of_death):
"""
雷克顿打内瑟斯
:param The_Butcher_of_the_sands:传内瑟斯数据
:param Desert_of_death:雷克顿数据
:return:
"""
print('即将被攻击的:%s, 当前血量 %s' % (Desert_of_death.get('name'),
Desert_of_death.get('health_point')))
Desert_of_death['health_point'] -= The_Butcher_of_the_sands['the_soul_from']
print('Desert_of_death:%s 使用 the_tyrant_beat 攻击 The_Butcher_of_the_sands:%s ,'
' The_Butcher_of_the_sands 掉血:%s 剩余血量:%s' % (The_Butcher_of_the_sands.get('name'),
Desert_of_death.get('name'), The_Butcher_of_the_sands.get('the_tyrant_beat'),
Desert_of_death.get('health_point'))) # 生产内瑟斯和雷克顿数据
p1 = Get_Desert_of_death('inside', 'soaring', 300, 4000)
p2 = Get_The_Butcher_of_the_sands('renekton', 'soaring', 350, 3500)
# 开打
Desert_of_death_attack(p1, p2)
"""
即将被攻击的:renekton, 当前血量 3500
Desert_of_death:inside 使用 the_soul_from 攻击 The_Butcher_of_the_sands:renekton ,The_Butcher_of_the_sands 掉血:300 剩余血量:3200
"""

两种编程思想

1.根据上方的演示我们明白了跟之前不太一样的编程思想,面向对象编程
2.面向过程编程,就是指我们之前写的代码,所有的数据都可以进行互相调用。
3.面向对象编程其实就是我们将他给绑定到一个地方也就是一个容器中,这个容器存储我们的数据和功能,我们虽然可以调用但是只要调用了那么你就是一个对象
4.面向对象和面向对象编程在我们的编程过程中都是一样的不存在哪个更好。并且经常在一起使用

对象与类型的概念

1.对象的概念
对象其实就是一个容器,我们可以在这个容器总存入数据和功能
2.类的概念
类其实就是类别和种类,我们可以也把他理解成一个容器,不过它内部的是多个对象,并且这些对象拥有相似的功能,而每个对象中只存了他自己所需要的数据,这样就极大的节省了内存,减少代码冗余。

对象与类的创建

1.什么是类
在我们现实生活中,一个人经常被成为是个体,而一群人则被成为群体也就是类。
2.对象是什么
对象其实就是将数据和功能绑定到一起,但是为了突出卖你想对象的形式然后python就专门为面向对象开发了以套专门用来操作秒你想对象的语法。
3.类的语法
class 类名:
# 类中对象的公共数据
# 类中对象的公共方法
3.1class是定义类的关键字
3.2类名和变量名函数名一样都需要做到见名知意并且建议首字母大写
3.3类体代码,也就是公共的数据和方法类体代码再定义阶段就会被执行

名称空间查找顺序

class Student: # 类的命名应该使用首字母大写

    school='清华大学' # 数据

    def choice(self): # 功能
print('choosing a course') # 选课 print(Student.__dict__) # 使用该方法查看名称空间 可以看成是一个字典
print(Student.__dict__['school']) # 使用字典的取值方式获取名字 # 清华大学
print(Student.__dict__.get('choice')) # 使用字典的取值方式获取名字
'''在面向对象编程中 想要获取名称空间中的名字 可以采用句点符'''
print(Student.school) # 清华大学
print(Student.choice) # <function Student.choice at 0x0000022915FDF820>
'''类实例化产生对象>>>: 类名加括号'''
stu1 = Student() # 清华大学
stu2 = Student() # <function Student.choice at 0x0000022915FDF820>
print(stu1.school) # 清华大学
print(stu2.school) # 清华大学
print(stu1) # <__main__.Student object at 0x000001D923B04A60>
print(stu2) # <__main__.Student object at 0x0000025E8A48F130>
print(stu1.__dict__, stu2.__dict__) # {} {}
print(stu1.school) # 清华大学
print(stu2.school) # 清华大学
print(stu1.choice) # <bound method Student.choice of <__main__.Student object at 0x0000022915EB2E80>>
print(stu2.choice) # <bound method Student.choice of <__main__.Student object at 0x0000022915EB2E80>>
Student.school = '北京大学' # 修改school键对应的值
print(stu1.school) # 北京大学
print(stu2.school) # 北京大学
"""
我们习惯将类或者对象句点符后面的东西称为属性名或者方法名
"""

对象的独有数据

1.方法一:
class Student:
school = '中国传媒大学'
def choice_course(self):
print('甄别课程')
obj1 = Student()
obj1.__dict__['name'] = 'joseph'
obj1.__dict__['age'] = 21
obj1.__dict__['hobby'] = 'read'
print(obj1.name) # joseph
print(obj1.age) # 21
print(obj1.hobby) # read
print(obj1.school) # 中国传媒大学
obj2 = Student()
obj2.__dict__['name'] = 'trump'
obj2.__dict__['age'] = 76
obj2.__dict__['hobby'] = 'golf'
print(obj2.name) # trump
print(obj2.age) # 76
print(obj2.hobby) # golf 2.方法二:
def init(obj, name, age, hobby):
obj.__dict__['name'] = name
obj.__dict__['age'] = age
obj.__dict__['hobby'] = hobby
Stu1 = Student()
Stu2 = Student()
init(Stu1, 'joseph', 21, 'read')
init(Stu2, 'Trump', 76, 'golf')
print(Stu1.__dict__) # {'name': 'joseph', 'age': 21, 'hobby': 'read'}
print(Stu2.__dict__) # {'name': 'Trump', 'age': 76, 'hobby': 'golf'} 3.方法三
class Student:
def __init__(self, name, age, hobby):
self.name = name # obj.__dict__['name'] = name
self.age = age # obj.__dict__['age'] = age
self.hobby = hobby # obj.__dict__['hobby'] = hobby
school = '中国传媒大学'
def choice_course(self):
print('选课')
stu1 = Student()
print(stu1.__dict__)
Student.__init__(stu1, 'joseph', 21, 'read')
print(stu1.__dict__)
print(stu1.name) stu1 = Student('joseph', 21, 'read')
print(stu1)
stu2 = Student('Trump', 76, 'golf')
print(stu2)

动静态方法

1.什么是方法
方法其实就是类体代码中编写的函数,每次传入时都会导出属于自己的数据,这种我们称之为方法。
2.绑定给对象的方法
对象调用的时候会将自身传入类体代码中,所以会产生一个独属于自己的数据也就是方法
3.静态方法(其实就是我们普通的有参函数)
class Game:
game_name = 'LOL'
# 绑定给对象的方法
def kill_enemy(self): # self来接收对象
print('你可也太强了', self)
@classmethod # 绑定给类的方法
def kill_nash_baron(cls): # 接受对象
print('大哥带带我', cls)
@staticmethod # 静态方法
def get_out(a, b): # 常规函数
print('自己一个人去玩吧,你可也太菜了')
Game1 = Game()
Game.kill_enemy(Game) # 你可也太强了 <class '__main__.Game'>
Game1.kill_enemy() # 你可也太强了 <__main__.Game object at 0x000001D86BB18C70>
Game.kill_nash_baron() # 大哥带带我 <class '__main__.Game'>
Game1.kill_nash_baron() # 大哥带带我 <class '__main__.Game'>
# 调用最普通的有参函数
Game.get_out(1, 2) # 自己一个人去玩吧,你可也太菜了
Game1.get_out(1, 2) # 自己一个人去玩吧,你可也太菜了

三大特征之传承

1.三大特征
1.1 继承
1.2 封装
1.3 多态
2.继承
继承其实和我们现实中的继承差不多其实就是我们从父辈那里的来他们的一些东西,在程序中其实也是一样的我们从父类代码中获取他的数据和功能,这种方法被我们称之为继承。
3.继承代码
class 类名(父类名):
pass
4.1 我们只需要在类名后方加一个括号
4.2 在括号内填入我们所需要的父类名就好了
4.3 父类是可以同时调用多个的只需要在父类名后面跟逗号就可以填写下一个父类名
class 类名 (父类名1, 父类名2, 父类名3......):
pass
我们在调用父类时一般是从左往右开始寻找
4.继承称谓
我们在继承中被继承的被成为:父类,基类和超类
在继承的类被称为:子类和派生类

继承的本质

1、所有的类都继承自object类,即所有的类都是object类的子类
2、子类一旦继承父类,则可以使用父类中除私有成员外的所有内
3、子类继承父类后并没有将父类成员完全赋值到子类中,而是通过引用关系访问调用
4、子类中可以定义独有的成员属性和方法
5、子类中定义的成员和父类成员如果相同,则优先使用子类成员
6、子类如果想扩充父类的方法,可以在定义新方法的同时访问父类成员来进行代码重用
7、可以使用 [父类名.父类成员] 的格式来调用父类成员,也可以使用[super().父类成员]的 格式来调用

不继承情况下下查找顺序

1.在没有继承任何类的情况下去查找顺序
class Game: # 创建一个类
game_name = 'LOL' # 命名类
def eat_river_crab(self): # 类中加函数也就是功能
print('吃河蟹') # 额吃game1 = Game() # 赋值
print(game1.game_name) # LOL 打印game1的值
game1.game_name = '云顶之奕' # 将game1的值修改
print(game1.game_name) # 云顶之奕 # 打印
game1print(Game.game_name) # LOL # 打印原本的Game的值也就是证明我使用后面赋值的值修改并不会修改原来数据的值,因为他已经保存到他自己的对象中

单继承情况下的查找顺序

1.单方面寻找
class A:
name = 'from A'
pass
class B(A):
name = 'from B'
pass
class C(B):
name = 'from C'
pass
class Myclass():
name = 'from Myclass'
pass
class Myclass2(C):
name = 'from Myclass2'
pass obj = Myclass()
print(obj.name) # from Myclass
obj.name = '浑身就像散架一样'
print(obj.name) # # from Myclass obj2 = Myclass2()
print(obj2.name) # 将自己的和C, B的注掉 from A
# 顺序 对象 >>> 类 >>> 父类
1.单方寻找但是自己也有值并且和第一种类重复
class A1:
def func1(self):
print('form func1')
def func2(self):
print('from func2')
def func3(self):
print('from func3')
self.func1() # obj.func1
class Myclass(A1):
def func1(self):
print('from Myclass')
obj = Myclass()
obj.func1() # from Myclass
obj.func3() # from func3,from Myclass 判断自己有没有(没有), 去父级中寻找找到了先打# 印来自func3,
# 然后往下走又是func1因为本质上其实还是obj.func1所以还是 自己的Myclass

多继承情况下的查找顺序

1.查找顺序内置方法mro()查看对象名的查找顺序
2.继承方式
非菱形继承(最后不会归总到一个我们自定义类上)
深度优先(每个分支都走到底 再切换)
菱形继承(最后归总到一个我们自定义类上)
广度优先(前面几个分支都不会走最后一个类 最后一个分支才会走)
3.代码
class A:
name = 'from A'
pass
class B():
name = 'from B'
pass
class C():
name = 'from C'
pass
class D(A):
# name = 'from D'
pass
class E(B):
# name = 'from E'
pass
class F(C):
# name = 'from F'
pass class Myclass(F):
# name = 'from Myclass'
pass obj = Myclass()
print(obj.name)
obj.name = '浑身就像散架一样'
print(obj.name) print(Myclass.mro()) # [<class '__main__.Myclass'>, <class '__main__.F'>, <class '__main__.C'>, <class 'object'>]
print(Myclass.__bases__) # (<class '__main__.F'>,)

经典类与派生类

1.经典类
什么都不继承
2.新式类
继承object或则其他类
3.类型存在
经典类只有在python2中才存在就是什么东西都没有继承。
新式类在我们的python2中和3中都有但是在py2中必须自己写后面的(object)而在python3中则不需要直接已经直接优化到内部不需要再也出来也默认有。
但是还是建议写成,增加兼容性
class Myfunc(object):
pass

派生类的概念

子类在内部写了和父类相同的代码,并且更加完善了代码扩展了其功能叫做派生。
class Person:
def __init__(self, name, age, hobby):
self.name = name
self.age = age
self.hobby = hobby class Teacher(Person):
def __init__(self, name, age, hobby, lever):
super().__init__(name, age, hobby)
self.lever = lever
class Student(Person):
pass t1 = Teacher('joseph', 21, 'read', 1/10)
p1 = Student('joseph', 21, 'read')
print(t1)
print(p1)
t1.__init__('joseph', 21, 'read', 1/10) class Myclass(list):
def append(self, value):
if value == 'joseph':
print('joseph 不许过')
return
super().append(value) object = Myclass()
object.append(520)
object.append(666)
object.append(999)
object.append('joseph') # joseph 不许过
object.append('Alice')
print(object) # [520, 666, 999, 'Alice']

三大特征之封装

1.封装其实就是将数据或者功能给她隐藏起来用户虽然也可以使用但是必须需要一些额外的操作打开对应的接口才可以去使用,而我们则需要在接口中添加操作去将他隐藏起来。
2.在类的定义中使用双下滑线开头的都是拥有隐藏属性的,后续的类或者对象都无法直接去获取和调用它
3.在我们的python中不会真正限制任何的代码,非常的贴心,所以我们要访问隐藏对象的时候也不是不能访问只是需要进行特殊处理一下
需要隐藏的数据:__变量名 >>> 调用数据: _类名__变量名
4.案例
class Student(object):
__school = '中国传媒大学'
## 公共功能
def __init__(self, name, age, hobby):
self.__name = name
self.__age = age
self.__hobby = hobby
# 接受学生信息
def check_info(self):
print("""
学生姓名:%s
学生年龄:%s
学生爱好:%s
""" %(self.__name, self.__age, self.__hobby))
# 学生修改信息
def set_info(self, name , age, hobby):
if len(name) == 0:
print('用户名不能为空')
return
if not isinstance(age, int):
print('年龄必须是数字')
return
if len(hobby) == 0:
print('爱好不能为空')
return
self.__name = name
self.__age = age
self.__hobby = hobby
stu = Student('joseph', 21, 'read')
print(stu)
print(stu.check_info)
print(stu.set_info('小娴是你嘛', 21, '今天刚好一年难受'))

propert伪装

1.可以理解为将方法伪装成数据
obj.name # 我们在调用数据的时候是需要使用句点符点的方式就可以调用
obj.func() # 而我们在调用方法的时候就需要给她加一个括号来调用,但是现在当我们有了伪装的时候只需要像调用数据一样只点一下就可以直接调用,给出一种错觉,这就是伪装
obj.func # 伪装后真假难辨,obj.func,雄兔脚朴素,雌兔眼迷离,双兔傍低走,安能辨我是雄雌。 身体健康指标:
体质指数(BMI) = 体重(kg) 身高 **2(m)
但是我感觉我好像不太健康的样子,太轻了
2.
class Person:
def __init__(self, name, weight, height):
self.name = name
self.weight = weight
self.height = height @property
def BMI(self):
return self.weight / (self.height ** 2) p1 = Person('joseph', 60, 178)
res = p1.BMI
print(res)
print(p1.BMI)
print(p1.name)
print(p1.weight)
print(p1.height)
3.
class Foo:
def __init__(self, val):
self.__NAME = val # 隐藏属性 @property
def name(self):
return self.__NAME
@name.setter
def name(self, value):
if not isinstance(value, str): # 在设定值之前进行类型检查 接收
raise TypeError('%s must be str' % value) # 如果不是字符串自动报错,我们所给他设置的错误
self.__NAME = value # 通过类型检查后,将value存放到真是的位置也就是隐藏的self.__NAME @name.deleter
def name(self):
raise PermissionError('Can not delete') # 如果要删除name则报错 obj = Foo('joseph')
print(obj.name) # joseph
obj.name = 999 # 返回第一个报错也就是必须为字符串我们给她修改成整型
print(obj.name) # 打印 报错必须为字符串
del obj.name # 如果要删除的话直接捕获让他报错删除不了

三大特征之多态

1.什么是多态
多态其实就是一种事物的多种形态
就像水就有三种形态:固态(冰), 气态(水蒸气), 液态(肥宅快乐水)
动物也分为门,纲, 目, 科, 属, 种等分类
2.案例
# 警察抓罪犯,警察和两条警犬打击犯罪警犬分两种一种追击敌人另一种搜寻毒品,携带不同的警犬执行不同的工作
class Dog(object): # 定义父类
def work(self): # 提供解决方法
pass
# 定义子类,子类重写父类代码,并定义派生对象
class ArmyDog(Dog): # 继承上方父类
def work(self): # 重写同名的代码
print('追击罪犯...')
class DrugDog(Dog):
def work(self):
print('追击毒品...')
# 定义人类
class Person(object):
def work_with_Dog(self, dog): # 传入不同的类型,生成不通过的类型
dog.work() # 调用
ad = ArmyDog() # 调用不同对象
dd = DrugDog() police = Person()
police.work_with_Dog(ad) # 追击罪犯...
police.work_with_Dog(dd) # 追击毒品...
3.多态的本质
多态其实就是很多类共同调用同一个类,但是这些近似的功能都有共同的名字,我们无论拿到什么东西只要是可以套用的就可以直接去调用
4.抽象类
import abc
# 指定metaclass属性将类设置为抽象类,抽象类本身只是用来约束子类的,不能被实例化
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod # 该装饰器限制子类必须定义有一个名为talk的方法
def talk(self): # 抽象方法中无需实现具体的功能
pass
class Person(Animal): # 但凡继承Animal的子类都必须遵循Animal规定的标准
def talk(self):
pass
def run(self):
pass
obj = Person()
4.鸭子类型
鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
我们并不关心对象是什么类型,到底是不是鸭子,只关心行为
鸭子类型在动态语言中经常使用,非常灵活,使得python不想java那样专门去弄一大堆的设计模式

文件属性

1.
操作系统
linux系统:一切皆文件
只要你能读数据 能写数据 那么你就是文件
内存
硬盘
class Txt: #Txt类有两个与文件类型同名的方法,即read和write
def read(self):
pass
def write(self):
pass class Disk: #Disk类也有两个与文件类型同名的方法:read和write
def read(self):
pass
def write(self):
pass class Memory: #Memory类也有两个与文件类型同名的方法:read和write
def read(self):
pass
def write(self):
pass
2. python:一切皆对象
只要你有数据 有功能 那么你就是对象
文件名 文件对象
模块名 模块对象

反射方法

1.反射是什么
反射其实就是一种使用字符串来操作对象数据和方法的的方式
对象通过字符串来自省的功能和方法
2.反射的使用方法
hasattr():判断对象是否含有某个字符串对应的属性
getattr():获取对象字符串对应的属性
setattr():根据字符串给对象设置属性
delattr():根据字符串给对象删除属性
3.getattr(核心) 判断类、对象或者模块中是否有相应的属性或方法。用法:getattr(obj,str,default=None) 判断obj中是否有str属性,有就返回,没有时有传入第三参数就返回第三参数,没有就报错。
class A:
name = 'joseph'
age = 21
print(getattr(A, 'name')) # joseph
print(getattr(A, 'language', 'notfound')) # notfound
4.setattr() 设置属性。第三参数为新的属性值
class A:
name = 'joseph'
age = 21
setattr(A, 'name', 'Alice')
setattr(A,'language', 'Chinese')
print(getattr(A, 'name')) # Alice
print(getattr(A, 'language', 'notfound')) # Chinese 5.hasattr
判断时候有某个属性,有就返回True,没有就返回False
class A:
name = 'joseph'
age = 21
if hasattr(A, 'name'):
print(getattr(A, 'name')) # joseph
6.delattr
删除某个属性
class A:
name = 'joseph'
age = 21 delattr(A, 'name')
print(hasattr(A, 'name')) # False
7.反射本文件
sys.modulses[__ name__]就是本文件对象。
import sys
class A:
def __repr__(self):
return '666'
if hasattr(sys.modules[__name__], 'A'):
print(getattr(sys.modules[__name__], 'A')) # <class '__main__.A'> # # 666

反射的实际应用

1.反射的用途
1、反射类中的变量 : 静态属性,类方法,静态方法
2、反射对象中的变量、对象属性、普通方法
3、 反射模块中的变量
4、反射本文件中的变量
2.应用
class FtpServer:
def serve_forever(self):
while True:
inp = input('input your cmd>>: ').strip()
cmd, file = inp.split()
if hasattr(self, cmd): # 根据用户输入的cmd,判断对象self有无对应的方法属性
func = getattr(self, cmd) # 根据字符串cmd,获取对象self对应的方法属性
func(file)
def get(self, file):
print('Downloading %s...' % file) def put(self, file):
print('Uploading %s...' % file)
obj = FtpServer()
obj.serve_forever()

反射的实战案例

1.案例1
import settings # 调用我们呢刚刚配置的文件
new_dic = {} # 制造一个空字典
print(dir(settings)) # 将settings内部的所有可以使用句点符点出来的功能都给他展示出来
# ['AGE', 'HOBBY', 'NAME', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
for i in dir(settings):
if i.isupper(): # 判断是否为纯大写,如果是纯大写的话那么就获取该大写名字所对应的值
value = getattr(settings, i) # 获得对所对应的属性
new_dic[i] = value # 生成一个字典属性将大写字母的值当作字典的k,然后属性当作v值并纯给之前定义的字典
print(new_dic) # 打印字典
2.模拟cmd终端命令
class windows():
def dir(self):
print('dir获取当前目录下所有文件名称')
def ls(self):
print('ls获取当前路径下所有文件名称')
def ipconfig(self):
print('ipconfig获取当前计算机的网卡信息')
obj = windows()
while True:
cmd = input('请输入您的指令')
if hasattr(obj, cmd):
cmd_name = getattr(obj,cmd)
cmd_name()
else:
print(f'{cmd} 不是内部命令或外部命令,也不是可运行的程序或批处理文件')

常见的魔法方法

1.常见魔法
class MyClass(object):
def __init__(self, name): # __init__() 用于初始化实例,所以该方法是在实例对象创建后被调用,它是实例级别的方法,用于设置对象属性的一些初始值
print('from__init__')
pass
self.name = name
def __str__(self): # print([对象]) 是个字符串的时候触发 __str__ 的执行
print('from__str__')
return f"对象名称:{self.name}"
def __call__(self, *args, **kwargs): # [对象] + ( ) 就触发 __call__ 的执行
print(args)
print(kwargs)
print('from __call__')
def __getattr__(self, item): # 在 [对象].[属性] 获取属性不存在的时候会触发它的执行
print('from __getattr', item)
return f'您想要获得的属性值:{item}不存在'
def __setattr__(self, key, value): # 在 [对象].[属性] = [值] 设置属性值的时候就会触发它的执行
print(key)
print(value)
print('from __setattr')
super.__setattr__(self, key, value)
def __del__(self): # 在 del [对象].[属性] 删除属性的时候会触发它的执行
print('from __del__')
pass
def __getattribute__(self, item): # 先执行 __getattribute__—>去类的名称空间找—>__getattr__(本质是去对象自己的名称空间找)
print('from __getattribute__')
return super(MyClass, self).__getattribute__(item)
def __enter__(self): # 上下文管理协议就是 with 语句, 为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__()和__exit__()方法
print('from __enter__')
def __exit__(self, exc_type, exc_val, exc_tb): # 如果__exit__()返回值为True,那么异常会被清空,就好像啥都没发生一样,with后的语句正常执行
print('from __exit__') obj = MyClass('joseph')
obj1 = MyClass('jason')
print(obj.name) # 获取对象拥有的属性名name
print(obj.age) # 获取对象不存在的属性名age
print(obj.pwd) # 获取对象不存在的属性名pwd
print(obj.__dict__)
print(obj.name)
# del obj
print(obj.name)
with obj as f:
print(f) with open() as f:
pass

元类简介

1.元类是什么
所有的对象都是实例化或者说是通过调用类而得到的,python中一切皆对象,通过class关键字定义的类本质也是对象,对象又是通过调用类得到的,因此通过class关键字定义的类肯定也是调用了一个类得到的,这个类就是元类。
2.怎么辨别元类
由于在python3中没有经典类和新式类的区别,因此python3中object是所有类的基类,那内置元类type又是什么?type是object类的类型,总结来说就是type是object的类型,同时,object又是type的基类,在python3中类和类型是同一种东西,因此对象.__class__和type(对象)得到的结果是一致的,object的基类为空,但是type的基类为object,但是object的类型又是type。
3.类型
object.__class__
<class 'type'>
type.__class__
<class 'type'>
object.__bases__()
type.__bases__
<class 'object'>
type(object)
<class 'type'>
type(type)
<class 'typ'>

产生类的两种方式

1.class关键字
class MyClass:
pass 2.利用元类type
type(类名,类的父类,类的名称空间) """
学习元类其实就是掌握了类的产生过程 我们就可以在类的产生过程中高度定制化类的行为
eg:
类名必须首字母大写
上述需求就需要使用元类来控制类的产生过程 在过程中校验
"""

元类的基本使用

1.只有继承了 type 的类才可以被称为元类
class MyMetaClass(type):
pass
2.如果像压迫切换产生类的元类的话只通过继承是不可以的,必须通过关键字的形式才可以进行转型
class MyClass(metaclass = MeMetaClass):
pass
3.__init__实例化
class MyMetaClass(type):
def __init__(self, what, bases=None, dict=None):
print('自己')
print('what', what) # 类名
print('bases', bases) # 类的父类
print('dict', dict) # 类的名称空间
if not what.istitel():
print('首字母必须大写如果不大写直接剔除')
raise Exception('首字母必须大写如果不大写直接剔除')
super().__init__(what, bases, dict)

元类的进阶操作

1.对象加括号执行产生的对象类内部加括号就可以操控内部对象
2.类加括号执行产生该类的元类里面的双下call
3.实例化对象并操控
class MyMetaClass(type):
def __call__(self, *args, **kwargs):
print('from __call__') # from __call__
if args:
raise Exception('需要根据形参传实参')
super().__call__(*args, **kwargs) # from __call__ class MyCalss(metaclass=MyMetaClass):
def __init__(self, name, age):
self.name = name
self.age = age
print('from __init__') # from __init__ obj1 = MyCalss('joseph', 21)
obj2 = MyCalss(name='joseph', age=21)

python金牌班第七周周末总结的更多相关文章

  1. python金牌班第五周周末总结

    python金牌班第五周周末总结 常见内置函数 1.abs # 求绝对值,将负数变为整数,并且得出的值只有正数print(abs(-999)) # 999 2.all # 当在经历条件判断时所有的返回 ...

  2. Python学习笔记第七周

    目录: 1.静态方法 @staticmethod 2.类方法    @classmethod 3.属性方法  @property 4.类的特殊成员方法 a) __doc__表示类的描述信息 b) __ ...

  3. 2003031121——浦娟——Python数据分析第七周作业——MySQL的安装及使用

    项目 要求 课程班级博客链接 20级数据班(本) 作业要求链接 Python第七周作业 博客名称 2003031121--浦娟--Python数据分析第七周作业--MySQL的安装及使用 要求 每道题 ...

  4. C语言--第七周作业评分(5班)

    作业链接:https://edu.cnblogs.com/campus/hljkj/CS2017-5/homework/1304 一.评分要求 要求1 完成PTA第七周所有题,总共两次题,每次12.5 ...

  5. python九周周末总结

    python九周周末总结 UDP协议 udp协议的交互模式服务端不需要考虑客户端是否退出,你发多少那么他就会按照你发的东西直接去传输给客户端不存在黏包现象 服务端: import socket ser ...

  6. 十周周末总结 MySQL的介绍与使用

    python 十周周末总结 MySQL的介绍与使用 MySQL字符编码与配置文件 查看数据库的基本信息(用户,字符编码) /s windos下MySQL默认的配置文件 my_default.ini 修 ...

  7. 20145213《Java程序设计》第七周学习总结

    20145213<Java程序设计>第七周学习总结 教材学习内容总结 周末快乐的时间总是短暂的,还没好好感受就到了要写博客的周日.有人喟叹时间都去哪儿了,那本周我们就来认识一下Java里的 ...

  8. C语言程序设计II—第七周教学

    第七周教学总结(8/4-14/4) 教学内容 本周的教学内容为:8.3 冒泡排序,知识点:指针与数组.重点难点:指针.数组与地址的关系:数组名作为函数参数.要求学生能够使用数组名作为函数参数进行熟练编 ...

  9. 20165225《Java程序设计》第七周学习总结

    20165225<Java程序设计>第七周学习总结 1.视频与课本中的学习: - 第十一章学习总结 MySQL数据库管理系统,简称MySQL,是世界上最流行的开源数据库管理系统,其社区版( ...

随机推荐

  1. Java 线程创建与常用方法

    进程与线程 进程 程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至 CPU,数据加载至内存.在指令运行过程中还需要用到磁盘.网络等设备.进程就是用来加载指令.管理内存.管理 IO ...

  2. java基础题(3)

    5.面向对象 5.1封装 5.1.1修改Data类的定义 描述 现有一个Data类,内部定义了属性x和y,在main方法中实例化了Data类,并计算了data对象中x和y的和.但是,Data类的定义存 ...

  3. React简单教程-6-单元测试

    前言 我想大部分人的前端测试,都是运行项目,直接在浏览器上操作,看看功能正不正常.虽然明明有测试库可以使用,但是因为"要快"的原因,让好好做测试变成了一件影响效率的事. 因为这种无 ...

  4. 接口测试postman深度挖掘应用①

    一.测试接口前需要搞明白的原理: 1.在讲如何使用postman时,我们首先应该要了解网络的请求相应的知识,下面以fiddle进行抓包为例分析: 通过fiddler抓包我们不难发现,客户端也就是用户会 ...

  5. 微信小程序使用 ECharts

    echarts-for-weixin 是 ECharts 官方维护的一个开源项目,提供了一个微信小程序组件(Component),我们可以通过这个组件在微信小程序中使用 ECharts 绘制图表. e ...

  6. 密码学系列之:PKI的证书格式表示X.509

    目录 简介 一个证书的例子 X.509证书的后缀 .pem .cer, .crt, .der .p7b, .p7c .p12 .pfx 证书的层级结构和交叉认证 x.509证书的使用范围 总结 简介 ...

  7. 深入理解 volatile 关键字

    volatile 关键字是 Java 语言的高级特性,但要弄清楚其工作原理,需要先弄懂 Java 内存模型.如果你之前没了解过 Java 内存模型,那可以先看看之前我写过的一篇「深入理解 Java 内 ...

  8. StringJoiner的使用

    1.添加字符串 add()方法 StringJoiner sj = new StringJoiner(","); sj.add("我爱你"); sj.add(& ...

  9. JAVA语言的跨平台性和JDK,JRE与JVM

    Java虚拟机--JVM ~JVM:java虚拟机简称JVM是运行所有java程序的假想计算机,是java程序的运行环境,是java最具有吸引力的特性之一,我们编写的java代码,都运行在JVM之上 ...

  10. html字符超长后自动隐藏

    style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"