反射,内置方法,__str__ __repr__
反射
反射用到的mmp模块
- def wahaha():print('wahaha')
- class QQxing:
- def __init__(self,name):
- self.name = name
- def ADCa(self):
- print('in ADCa',self.name)
- # a
- # b
- # wahaha
- # QQxing
- # getattr('a')
- import sys
- print(sys.modules)
- print(sys.modules[__name__])
- print(getattr(sys.modules[__name__],'a'))
- print(getattr(sys.modules[__name__],'b'))
- getattr(sys.modules[__name__],'wahaha')()
- name1='aaa'
name2='bbb'
name3='ccc'
inp=input('>>>')
print(inp)
- class A:
- Name1 = 'aaa'
- Name2 = 'bbb'
- Name3 = 'ccc'
- def __init__(self,name):
- self.name=name
- def func(self):
- print('in func',self.name)
图示帮助理解
- a1=A('ddd')#实例化了一个ddd
- a1.func()#调用了func函数 in func ddd
- print(a1.name)#打印函数中名字 ddd
- getattr(a1,'func')#'func'是字符串类型的变量名
- getattr(a1,'func')() #in func ddd 加上括号执行函数
- print(getattr(a1,'func'))#打印的是地址
- print(getattr(a1,'name'))#打印实例化后,a1对应的名字
- if hasattr(A,'Name1'):
- print(getattr(A,'Name1'))#和hasattr搭配使用 #Name1
- print(getattr(A,'Name2')) #Name2
- print(getattr(A,'Name3')) #Name3
- while True:
- inp=input('>>>')
- if hasattr(A,inp):
- print(inp)
- 使用字符串数据类型的变量名来操作一个变量的值
使用反射获取某个命名空间的值
需要
有一个变量指向这个命名空间的字符串数据类型的名字,
再使用getattr获取值
如果是变量,能直接获得结果
如果是函数,只能拿到内存地址,加上括号就是执行
使用类名反射:静态属性,类方法,静态方法
使用对象名反射:对象属性,类中的普通方法
使用模块名反射:变量,函数,类
在自己所在的文件夹中反射全局变量:getattr(sys.modules[__name__],'要反射的名字')
- import mmp
- print(mmp.a)#直接使用模块,调用模块中的变量
- print(getattr(mmp,'a'))#使用反射,调用模块中的变量a
- mmp.wahaha()#直接使用模块调用模块中的函数
- getattr(mmp,'wahaha')()#使用反射调用模块中的函数
- print(mmp.QQxing)#直接使用模块,获取类的内存地址
- taibai=mmp.QQxing('太亮')#实例化模块中的类
- taibai.ADCa()#实例调用方法
- cls=getattr(mmp,'QQxing')#使用反射得到模块中类
- ret=cls('光头')#将得到的类实例化
- print(ret)#<mmp.QQxing object at 0x0000021FA2805D30>
- getattr(ret,'ADCa')()#in ADCa 光头 使用反射调用类中的方法
- hasattr ******
getattr ******
setattr ***
delattr *
- import mmp
- class A:
- Name1='alex'
- Name2='taibai'
- Name3='egon'
- def __init__(self,name):
- self.name=name
- def func(self):
- print('in func,self.name')
- A.Country='中国'#增
- A.Name1='alex_NB'#改
- print(A.__dict__)#查看类下的内容
- setattr(A,'Country','印度')#将中国改为印度
- print(A.__dict__)#查看类下的内容
- setattr(A,'Role','Person')#增加一个静态属性 'Role'='Person'
- print(A.__dict__)#查看类下的内容
- delattr(A,'Name1')#删除Name1='alex'的静态变量
- print(A.__dict__)#查看类下的内容
内置方法
- isinstance(obj,cls)检查是否obj是否是类 cls 的对象
issubclass(sub, super)检查sub类是否是 super 类的派生类
- a=10
- print(isinstance(a,int))#True
- class F:pass
- class Foo(F):pass
- obj=Foo()
- print(isinstance(obj,Foo))#True
- print(type(obj)is Foo)#True
- print(isinstance(obj,F))#True
- print(type(obj)is F)#False
- class F:pass
- class Foo(F):pass
- print(issubclass(Foo,F))#True
- print(issubclass(F,Foo))#False
- 类的内置方法 双下方法 魔术方法
对象加上(),可以调用这个类的__call__方法。
- class Foo:
- def __call__(self):
- print('call')
- Foo()()#call
- obj=Foo()
- obj()#相当于调用__call__call
- 内置函数的len函数是依赖类中的__len__
- class Classes:
- def __init__(self,student_lst):
- self.student_lst=student_lst
- def __len__(self):return len(self.student_lst)
- clas=Classes(['张三','李四','王五'])
- print(len(clas.student_lst))#不依赖__len__
- print(len(clas))#依赖__len__
- class Wahaha:
- def __init__(self,num,name,age):
- self.num=num
- self.name=name
- self.age=age
- def __len__(self):
- return len(self.__dict__)#返回类中属性的个数
- obj=Wahaha(6,'alex',8)
- print(len(obj.__dict__))#
- print(len(obj))#3 依赖__len__
- __eq__ 判断值是否相等的时候依赖__eq__的结果
- class QQxing:pass
- # def __eq__(self,other):本题中没有用到函数的内容(__eq__ 方法)
- # if type(self)==type(other) and self.__dict__==other.__dict__:
- # return True
- # else:
- # return False
- q1=QQxing()
- q1.name='alex'
- q2=QQxing()
- q2.name='egon'
- print(q1,q2)#两个内存地址不同
- print(q1==q2)# 两个自定义对象之间是否值相等,会根据内存地址去判断
- 面试题 判断值是否相等的时候依赖__eq__的结果,==就是在内部调用了__eq__方法
- 两个对象的名字和性别相同,那么这两个对象就是同一个人
- class Person:
- def __init__(self,name,sex,age):
- self.name=name
- self.sex=sex
- self.age=age
- def __eq__(self,other):
- if type(self)==type(other) and self.name==other.name and self.sex==other.sex :
- return True
- else:return False
- p1=Person('松松','男',23)
- p2=Person('松松','男',24)
- p3=Person('小灰灰','男',23)
- print(p1==p2)#True
- print(p1==p3)#False
- print(p2==p3)#False
- hash() 在内存的优化上起到了作用
- dict,set
- 两个对象的名字和性别相同,那么这两个对象就是同一个人,对10个对象进行去重
- class Person_lst:
- def __init__(self,name,sex,age):
- self.name=name
- self.sex=sex
- self.age=age
- def __hash__(self):
- return hash(self.name+self.sex)
- def __eq__(self,other):
- if type(self)==type(other) and self.name==other.name and self.sex==other.sex :
- return True
- else:return False
- l1=[('松松','男',23),('松松','男',24),('松松','女',23),('灰灰','男',23),('灰灰','男',24),\
- ('灰灰','女',23),('张三','男',23),('李四','男',23),('王五','男',23),('李六','男',23),]
- # p1=Person_lst(l1)
- p1=[Person_lst(i[0],i[1],i[2],) for i in l1]
- p2=list(set(p1))
- print(p2)
- for i in p2:
- # print(i.__dict__)#以字典的形式打印出来,因为类的空间里就是以这种方式储存的。
- print(list(i.__dict__.values()))#将p2(类)空间中的内容打印出来。
- class Person_lst:#巧用内置方法
- def __init__(self,name,sex,age):
- self.name=name
- self.sex=sex
- self.age=age
- def __hash__(self):
- return hash(self.name+self.sex)
- def __eq__(self,other):
- if type(self)==type(other) and self.name==other.name and self.sex==other.sex :
- return True
- else:return False
- def __str__(self): # 必须返回一个str数据类型
- return ','.join([self.name,self.sex,str(self.age)])
- l1=[('松松','男',23),('松松','男',24),('松松','女',23),('灰灰','男',23),('灰灰','男',24),\
- ('灰灰','女',23),('张三','男',23),('李四','男',23),('王五','男',23),('李六','男',23),]
- # p1=Person_lst(l1)#不能直接传列表,__init__方法的三个参数传不进去
- p1=[Person_lst(i[0],i[1],i[2],) for i in l1]#一次性实例化10个对象
- p2=list(set(p1))#利用集合去重
- # print(p2)#打印的是地址
- for i in p2 :#将筛选过的打印出来
- print(i)
- print(hash(p1[0]))#
- print(hash(p1[1]))#
- print(hash(p1[2]))#
- print(hash(p1[3]))#-5720704507138757199
- print(hash(p1[4]))#-5720704507138757199
- print(hash(p2[4]))#-8555849577569044973
- print(hash(p2[5]))#
- print(hash(p2[7]))#
- p1第一个和第二个,第四个和第五个判定为同一个人,所以hash值相等
- p2中已经去重了,所以每个人的hash值不相等
- hash(obj1)==hash(obj2) and obj1.__eq__(obj2):是重复的
- obj1.__hash__()==obj2.__hash__() and obj1.__eq__(obj2):是重复的
- py 2.7
- class Person:
- def __init__(self,name,age,sex):
- self.name=name
- self.age=age
- self.sex=sex
- person_lst=[Person('egon',i,'male') for i in range(100)]
- for i in set(person_lst):
- print(list(i.__dict__.values()))
__str__ __repr__
- l=[1,2,3]#实际是列表的实例化
a='cba'
# 语法糖
print(a)
print(1)
- class QQxing:pass
- q1=QQxing()
- print(q1)#内存地址
- class Course:
- def __init__(self,name,price,period):
- self.name=name
- self.price=price
- self.period=period
- def __str__(self):
- return '*'.join([self.name,str(self.price),self.period])#列表转字符串,用join
- python=Course('python',19800,'6month')
- linux=Course('linux',17800,'6month')
- for i in [python,linux]:
- print(i)#python*19800*6month linux*17800*6month
- print(python)#没有__str__方法,打印出来的是内存地址
- print('course:%s' % python)#course:python*19800*6month
- print('a:',str(python))#a: python*19800*6month
- __str__方法和str(),print() %s 都是息息相关的
- class Student:
- def __init__(self,name,sex,age):
- self.name=name
- self.sex=sex
- self.age=age
- def __repr__(self):
- return self.name
- stu1=Student('光头','男',25)
- print('学生姓名:%r' % stu1)#学生姓名:光头
- print(repr(stu1))#光头
- __repr__方法 和repr() %r 都是息息相关的
- class Student:
- def __init__(self,name,sex,age):
- self.name=name
- self.sex=sex
- self.age=age
- # def __str__(self):
- # return '&'.join([self.name,self.sex,str(self.age)])
- # def __repr__(self):
- # return self.name
- def __repr__(self):
- return ':'.join([self.name,self.sex,str(self.age)])
- stu1=Student('光头','男',25)
- print('%s' % stu1)#光头:男:25
- print('学生:%r' % stu1)#学生:光头:男:25
- print(str(stu1))#光头:男:25
- print(repr(stu1))#光头:男:25
- 在没有实现__str__方法的情况下,__repr__能够完全代替__str__的功能
- 但是__str__不能代替__repr__的工作
- 在__repr__和__str__都存在的情况下:
- __repr__方法 和repr() %r 都是息息相关的
- __str__方法和str() % r都是息息相关的
- *coding:utf_8*
- format_dict={
- 'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
- 'tna':'{obj.type}:{obj.name}:{obj.addr}',
- 'tan':'{obj.type}*{obj.addr}*{obj.name}',
- }
- class School:
- def __init__(self,name,addr,type):
- self.name=name
- self.addr=addr
- self.type=type
- def __format__(self,format_spec):#format_spec='nat'
- if not format_spec or format_spec not in format_dict:
- format_spec='nat'
- fmt=format_dict[format_spec]#fmt='{obj.name}-{obj.addr}-{obj.type}'
- return fmt.format(obj=self)#'{obj.name}-{obj.addr}-{obj.type}'.format(obj=self) 格式化输出
- s1=School('清华','北京','公立')
- print(format(s1,'nat'))#清华-北京-公立
- print(format(s1,'tna'))#公立*清华1:北京
- print(format(s1,'tan'))#公立*北京*清华1
- print(format(s1,'iwejkwocoi'))#清华1-北京-公立
- class A:pass
- o=A()
- o.name='a'
- o.addr='b'
- o.type='c'
- print('{obj.name}-{obj.addr}-{obj.type}'.format(obj=o))#格式化输出
- 总结:
- 反射 —— 明显的简化代码
- 能拿到的变量名本来就是一个字符串的时候
- 用户输入的、文件读入的、网络上传输
- hasattr 判断某个变量在不在命名空间中
- getattr 获取某个名空间中的变量
- setattr 给空间中的某个变量赋值、或者创建变量
- delattr 从空间中删除某个变量
- ***所有的变量都是字符串数据类型的变量名
- 内置方法
- 内置方法,内置函数,内置的模块
- 你自定义的类或者对象
- 能否利用一些内置函数,内置模块实现功能
- 你的内置方法是否实现了响应的功能
- hash()函数就依赖__hash__方法
- len()函数就依赖__len__方法
- ==函数就依赖__eq__方法
- format函数就依赖__format__方法
- str,print,%s函数就依赖__str__方法
- repr,%r函数就依赖__repr__方法
- * 在没有str的时候所有的引用__str__方法的
- 地方都可以自动引用__repr__方法
- set 依赖 __hash__和__eq__方法来完成去重
123
反射,内置方法,__str__ __repr__的更多相关文章
- 内置方法 __str__ __repr__
内置方法(双下方法,魔术方法) 在不需要程序员定义,本身就存在的类中的方法就是内置方法 内置方法: __名字__ __init__ 不需要我们主动调用,而是在实例化的时候内部自动调用的,存在一种 ...
- 第8.14节 Python类中内置方法__str__详解
一. object类内置方法__str__和函数str 类的内置方法__str__和内置函数str实际上实现的是同一功能,实际上str调用的就是__str__方法,只是调用方式不同,二者的调用语法如下 ...
- python 字典内置方法get应用
python字典内置方法get应用,如果我们需要获取字典值的话,我们有两种方法,一个是通过dict['key'],另外一个就是dict.get()方法. 今天给大家分享的就是字典的get()方法. 这 ...
- Python的内置方法,abs,all,any,basestring,bin,bool,bytearray,callable,chr,cmp,complex,divmod
Python的内置方法 abs(X):返回一个数的绝对值,X可以是一个整数,长整型,或者浮点数,如果X是一个复数,此方法返回此复数的绝对值(此复数与它的共轭复数的乘积的平方根) >>> ...
- 多态 鸭子类型 反射 内置方法(__str__,__del__) 异常处理
''' 1什么是多态 多态指的是同一种/类事物的不同形态 2 为何要有多态 多态性:在多态的背景下,可以在不用考虑对象具体类型的前提下而直接使用对象 多态性的精髓:统一 多态性的好处: 1增加了程序的 ...
- python基础之反射内置方法元类
补充内置函数 isinstance(obj,Foo) # 判断obj是不是foo的实例 issubclass() # 判断一个类是不是另一个类的子类 反射 什么是反射? 通过字符串来操作 ...
- 6.python字符串-内置方法列举
所谓内置方法,就是凡是字符串都能用的方法,这个方法在创建字符串的类中,下面是总结: 首先,我们要学习一个获取帮助的内置函数 help(对象) ,对象可以是一个我们创建出来的,也可以是创建对象的那个类, ...
- python字符串内置方法
网上已经有很多,自己操作一遍,加深印象. dir dir会返回一个内置方法与属性列表,用字符串'a,b,cdefg'测试一下 dir('a,b,cdefg') 得到一个列表 ['__add__', ' ...
- Python的内置方法
一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object) ...
- python黑魔法 -- 内置方法使用
很多pythonic的代码都会用到内置方法,根据自己的经验,罗列一下自己知道的内置方法. __getitem__ __setitem__ __delitem__ 这三个方法是字典类的内置方法,分别对应 ...
随机推荐
- 仿log4j 写 log 代码
log4j 一直有个问题无法满足我,有可能我还不知道怎么去使用它. 就是他会把项目中所有的日志信息都记到一个文件里面,而业务系统往往需要根据某个业务流程查看日志分析. public class Bus ...
- Qt开发经验小技巧11-20
获取类的属性 const QMetaObject *metaobject = object->metaObject(); int count = metaobject->propertyC ...
- server2008r2 安装CentOS
一:安装CentOS 二:配置虚拟网络: 三:设置创建的虚拟机使用刚才创建的网卡: 四:运行CentOs,输入用户:root 密码:root,登录后输入: dhclient 自动获取IP ip ...
- 快排的时间复杂度O(n) = nlogn计算过程
转载:https://www.cnblogs.com/javawebsoa/p/3194015.html 本文以快速排序为例,推导了快排的时间复杂度nlogn是如何得来的,其它算法与其类似. 对数据D ...
- springboot2 配置 https
package cn.xiaojf.aibus.configure; import org.apache.catalina.Context; import org.apache.catalina.co ...
- elementui禁用全选按钮
document.getElementsByClassName('el-checkbox__input')[0].classList.add('is-disabled') doc ...
- Java开发笔记(一百零七)URL地址的组成格式
URL的全称是Uniform Resource Locator,意思是统一资源定位符,俗称网络地址或网址.网络上的每个文件及接口,都有对应的URL网址,它规定了其他设备如何通过一系列的路径找到自己,犹 ...
- js中引用类型Math一些常用的方法和属性
js中有一种引用类型叫做Math,和Global属于单体内置对象,里面有一些非常常用的数学方法和数学常量 常用数学常量 Math.E; // 自然对数的底数Math.LN10 10的自然对数 Math ...
- python 之 Django框架(APP和ORM的使用)
12.3 APP 12.31 创建APP 一个Django项目可以分为很多个APP,用来隔离不同功能模块的代码 用命令行创建一个APP: python3 manage.py startapp app0 ...
- PAT(B) 1070 结绳(Java)
题目链接:1070 结绳 (25 point(s)) 题目描述 给定一段一段的绳子,你需要把它们串成一条绳.每次串连的时候,是把两段绳子对折,再如下图所示套接在一起.这样得到的绳子又被当成是另一段绳子 ...