一、反射
反射:使用字符串数据类型的变量名来获取这个变量的值
input:用户输入的如果是a,那么打印1。如果输入的是b那么就打印2.如果输入name,那么打印alex
文件:从文件中读出的字符串,想转换成变量的名字
网络:将网络传输的字符串转换成变量的名字
1.反射类中的变量:静态属性,类方法
# class Foo:
# School = 'oldboy'
# Country = 'China'
# language = 'Chinese'
# @classmethod
# def class_method(cls):
# print(cls.School)
# @staticmethod
# def static_method():
# print(Foo.School)
# # 反射实现
# while True:
# inp = input('>>>')
# if hasattr(Foo,inp):
# print(getattr(Foo,inp))
#
# getattr(Foo,'class_method')()
# getattr(Foo, 'static_method')()
解析getattr方法:
# 解析getattr方法: # getattr(变量名: 命名空间, 字符串:属于一个命名空间内的变量名) # getattr(Foo, 'School') # 相当于Foo.School # print(Foo.class_method) # print(getattr(Foo, 'class_method')) # 地址一样
2.反射模块中的变量
import os
# so.rename('a', 'b')
# getattr(os, 'rename')('a', 'b')
3.反射本文件中的变量
# a = 1 # b = 2 # name = 'alex' # def qqxing(): # print('qqxing') # # # import sys # print(sys.modules['__main__']) # 本文件的命名空间 # print(sys.modules['__main__'].a) # print([__name__]) # 变量,内置的变量
# 反射本文件中的变量 结论 # a = 1 # b = 2 # name = 'alex' # def qqxing(): # print('qqxing') # class Foo:pass # # import sys # print(sys.modules[__name__]) # 反射本文件中的变量 固定的使用这个命名空间 # print(getattr(sys.modules[__name__],'a')) # print(getattr(sys.modules[__name__],'b')) # print(getattr(sys.modules[__name__],'name')) # getattr(sys.modules[__name__],'qqxing')() # print(getattr(sys.modules[__name__],'Foo')) # obj = getattr(sys.modules[__name__],'Foo')() # print(obj)
4.setattr
# class Foo:
# Country = 'China'
#
# def func():
# print('qqxing')
# Foo.School = 'OLDBOY'
# setattr(Foo,'School','OLDOBY') # 接受三个参数 命名空间 ‘变量名’ 变量值
# print(Foo.__dict__)
# print(getattr(Foo,'School'))
# print(Foo.School)
# #
# setattr(Foo,'func',func) # 一般没人往空间中添加函数
# print(Foo.__dict__)
# print(Foo.func)
5.delattr
# delattr # del Foo.Country # print(Foo.__dict__) # delattr(Foo,'Country') # print(Foo.__dict__)
二、内置方法
定义:不需要程序员定义,本身就存在类中的方法就是内置方法
内置方法的形式:__名字__
名字又称为:双下方法,魔术方法,内置方法
作用:不需要我们主动调用,而是实例化时内部自动调用的。
所有的双下方法,都不需要我们直接区调用,都有另外一种自动触发他的语法。
1.__str__ 和 __repr__
# __str__ __repr__
# class Course:
# def __init__(self,name,period,price,teacher):
# self.name= name
# self.period = period
# self.price = price
# self.teacher = teacher
#
# def __str__(self):
# return 'str : %s %s %s %s' % (self.name, self.period, self.price, self.teacher)
#
# def __repr__(self):
# return 'repr : %s %s %s %s' % (self.name, self.period, self.price, self.teacher)
# course_lst = []
# python = Course('python','6 month',29800,'boss jin')
# course_lst.append(python)
# linux = Course('linux','5 month',25800,'oldboy')
# course_lst.append(linux)
# for id,course in enumerate(course_lst,1):
# print('%s %s %s %s %s'%(id,course.name,course.period,course.price,course.teacher))
# print(id,course)
# print('%s %s'%(id,course))
# print(str(course))
# print(repr(course))
# print('%r'%course)
区别
__str__ 当你打印一个对象的时候 触发__str__ 当你使用%s格式化的时候 触发__str__ str强转数据类型的时候 触发__str__ __repr__ repr是str的备胎 有__str__的时候执行__str__,没有实现__str__的时候,执行__repr__ repr(obj)内置函数对应的结果是 __repr__的返回值 当你使用%r格式化的时候 触发__repr__
顺序
子类有__str__:Son.str 子类没有__str__:找父类,Foo.str 子类父类都没有__str__:Son.repr 子类父类都没有str,子类有repr:Son.repr 否则:Foo.repr
class Foo:
# def __str__(self):
# return 'Foo.str'
def __repr__(self):
return 'Foo.repr'
class Son(Foo):
pass
# def __str__(self):
# return 'Son.str'
# def __repr__(self):
# return 'Son.repr'
s1 = Son()
print(s1)
2.构造方法__new__
在init之前,实例化对象的第一步是 __new__创建了一个空间
class Foo:
def __init__(self): # 初始化方法
print('执行init')
def __new__(cls, *args, **kwargs): # 构造方法
print('执行new')
return object.__new__(cls)
obj = Foo()

# 单例模式 # 一个类 只有一个实例的时候,单例模式 class Foo: __instance = None def __init__(self, name, age): # 初始化方法 print('执行init') self.name = name self.age = age def __new__(cls, *args, **kwargs): # 构造方法 if cls.__instance is None: cls.__instance = object.__new__(cls) return cls.__instance obj1 = Foo('alex', 20) obj2 = Foo('egon', 22) print(obj1.name, obj2.name)
3.析构方法__del__
析构方法:在删除这个类创建的对象的时候会先从这个方法出发,再删除对象。做一些清理工作,比如说关闭文件,关闭网络的链接,数据库的链接。
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
self.file = open('file', 'w')
def write(self):
self.file.write('jsjgjs')
def __del__(self): # 析构方法:在删除这个类创建的对象的时候会先出发这个方法,再删除对象。
# 做一些清理工作,比如说关闭文件,关闭网络的链接,数据库的链接
self.file.close()
print('执行del了')
f = Foo('alex', 20)
del f.name
4.__len__
# len() list dict set str
print('__len__' in dir(list))
print('__len__' in dir(dict))
print('__len__' in dir(set))
print('__len__' in dir(str))
print('__len__' in dir(int))
print('__len__' in dir(float))
class Foo:
def __len__(self):
return 2
obj = Foo()
print(len(obj)) # 2
class Team:
def __init__(self, name, course):
self.name = name
self.course = course
self.students = []
def __len__(self):
return len(self.students)
s1 = Team('team', 'pirate')
s1.students.append('luffy')
s1.students.append('zoro')
s1.students.append('sanji')
print(len(s1))
5.__eq__
class Staff:
def __init__(self, name, sex):
self.name = name
self.sex = sex
def __eq__(self, other):
return self.__dict__ == other.__dict__
# return True
luffy = Staff('luffy', 'male')
luffy2 = Staff('luffy', 'male')
zoro = Staff('zoro', 'male')
print(luffy == luffy2)
print(luffy == zoro) # 正常是False, 如果return True 返回的是True。
l1 = [1,2,3,4]
l2 = [1,2,3,4]
print(id(l1),id(l2))
print(l1 == l2)
print(l1 is l2)
6.__hash__
class Foo:
pass
obj1 = Foo()
obj2 = Foo()
print(hash(obj1)) # 116451029964
print(hash(obj1)) # 116451029964
print(hash(obj1)) # 116451029964
print(hash(obj1)) # 116451029964
print(hash(obj2)) # -9223371920403745862
# 相同的值hash得到的值是一样的
# 1.每次执行的hash值都会变
# 2.在一次执行的过程中对同一个值的hash结果总是不变的
hash算法:
1.对于相同的值在一次程序的运行中是不会变化的
2.对于不同的值在一次程序的运行中总是不同的
# set的去重机制 # new_lst = [1,2,3,4,5,6,7,8,9,0,10,111,238579] # lst = [2,2,43,53,238579,14780] # for i in lst: # if i in new_lst: # pass # else: # new_lst.append(i) # set = {1,2,'abc',3,4,5,6,7,8,9,'bca'} # 不能通过逐个判断值相等这件事儿来做去重工作 # hash算法也不是完全的靠谱 # set 的去重机制 # 1.对每一个元素进行hash计算出一个内存地址 # 2.到这个内存地址上查看 # 如果这块内存中没有值 # 将这个元素存到对应的内存地址上 # 如果这块内存中已经有值 # 判断这两个值是否相等 # 如果相等 就舍弃后面的值 # 如果不相等 就二次寻址再找一个新的空间来存储这个值
# 员工类 # 姓名 年龄 性别 部门 # 转岗位 # 姓名 年龄变化了 性别 部门 # 100个员工,去掉重复的 # 员工的姓名 性别 是相同的,就认为是同一个员工 class Staff: def __init__(self,name,age,sex,dep): self.name = name self.age = age self.sex = sex self.dep = dep def __hash__(self): return hash(self.name + self.sex) def __eq__(self, other): if self.name == other.name and self.sex == other.sex: return True name_lst = ['yuan','egon','nazha','peiqi'] obj_lst = [] for i in range(100): name = name_lst[i%4] obj = Staff(name,i,'male','python') obj_lst.append(obj) print(obj_lst) ret = set(obj_lst) print(ret) for i in ret: print(i.name,i.age)