Python学习日记(二十七) 反射和几个内置函数
isinstance()
判断isinstance(obj,cls)中obj是否是cls类的对象
class Person:def __init__(self,name):self.name = name p = Person('Jane') print(isinstance(p,Person)) #True
issubclass()
判断issubclass(sub,super)中sub是否是super类的派生类
class Person:def __init__(self,name):self.name = name class Father(Person):pass print(issubclass(Father,Person)) #True print(issubclass(Person,Father)) #False
反射
反射就是用字符串类型的名字去操作变量,python中的一切事物皆为对象(都可以使用反射)
1.hasattr()
函数用于判断对象是否包含对应的属性,通常和getattr一起搭配使用,先用hasattr判断是否这个对象含有这个属性,如果有就通过getattr来拿值,如果没有就提示没有这个属性
class Person:age = 20def __init__(self,name,height,weight):self.name = nameself.height = heightself.weight = weightdef fuc(self):print('weight...height...') #1 if hasattr(Person,'age'):print(getattr(Person,'age')) #20 else:print('没有这个类属性!') #2 p = Person('Adson',1.6,75) if hasattr(p,'bmi'):print(getattr(p,'bmi')) else:print('没有这个属性!') #没有这个属性! #3 if hasattr(p,'fuc'):getattr(p,'fuc')() #weight...height... else:print('没有这个方法!')
2.getattr()
函数用于返回一个对象属性值
(1)反射对象的属性
class A:def __init__(self,name):self.name = name a = A('Adson') ret = getattr(a,'name') print(ret) #Adson
(2)反射对象的方法
class A:def fuc(self):print('This is fuc!') a = A() ret = getattr(a,'fuc') print(ret) #<bound method A.fuc of <__main__.A object at 0x00000000024E1C88>> 获得一个绑定方法的地址 ret() #This is fuc! 在ret后加上括号去调用方法
(3)反射类的属性
class A:age = 18 ret = getattr(A,'age') print(ret) #18
(4)反射类的方法(classmethod、staticmethod)
一般的调用方式是类名.方法名
class A:@classmethoddef fuc(cls):print('This is class fuc!') ret = getattr(A,'fuc') print(ret) #<bound method A.fuc of <class '__main__.A'>> 获得一个绑定方法 ret() #This is class fuc! getattr(A,'fuc')() #This is class fuc! 简写
(5)反射模块的变量
先建立一个模块,模块名pyfile.py,增加一个变量
dic = {'apple' : 18,'banana' : 20}
然后通过我的模块反射pyfile模块的变量
import pyfile print(pyfile.dic) #{'apple': 18, 'banana': 20} ret = getattr(pyfile,'dic') print(ret) #{'apple': 18, 'banana': 20}
(6)反射模块的方法
先建立一个模块,模块名pyfile.py,增加一个方法
def fuc():print('abc123aaa!!!')
然后通过我的模块反射pyfile模块方法
import pyfile ret = getattr(pyfile,'fuc') print(ret) #<function fuc at 0x0000000002498D08> ret() #abc123aaa!!! getattr(pyfile,'fuc')() #abc123aaa!!!
(7)反射模块的类
先建立一个模块,模块名pyfile.py,增加一个类
class B:price = 200def __init__(self,name):self.name = namedef fuc(self):print('This classB fuc..' + self.name)
然后通过我的模块反射pyfile模块方法
import pyfile b = getattr(pyfile,'B')('Josn') #getattr相当于拿到了这个模块的B类 并进行实例化了一个b对象 print(b.__dict__) #{'name': 'Josn'} print(b.price) #200 b.fuc() #This classB fuc..Josn
(8)反射自身模块的变量
通过sys.modules['__main__']找到当前的模块
import time import sys t = time.asctime(time.localtime(time.time())) print(t) #Mon Sep 9 22:36:40 2019 print(sys.modules['__main__']) #<module '__main__' from 'C:/Users/Administrator/PycharmProjects/PYL/temp_file/temp_py.py'> print(sys.modules['__main__'].t) #Mon Sep 9 22:38:01 2019 ret = getattr(sys.modules['__main__'],'t') print(ret) #Mon Sep 9 22:39:05 2019
(9)反射自身模块的方法
import sys def fuc():print('abc123...') ret = getattr(sys.modules['__main__'],'fuc') print(ret) #<function fuc at 0x0000000002798730> ret() #abc123... getattr(sys.modules['__main__'],'fuc')() #abc123...
3.setattr()
用于设置属性值,该属性不一定是存在的
class Person:age = 20def __init__(self,name,height,weight):self.name = nameself.height = heightself.weight = weight #对一个对象修改 p = Person('Adson',1.6,75) setattr(p,'name','Jane') setattr(p,'height',1.7) setattr(p,'gender','male') print(p.__dict__) #{'name': 'Jane', 'height': 1.7, 'weight': 75, 'gender': 'male'} #对一个类修改 print(Person.__dict__) #{'__module__': '__main__', 'age': 20, '__init__': <function Person.__init__ at 0x0000000002548950>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None} setattr(Person,'age',21) setattr(Person,'name','Jane') setattr(Person,'height',1.7) setattr(Person,'gender','male') print(Person.__dict__) #{'__module__': '__main__', 'age': 21, '__init__': <function Person.__init__ at 0x0000000002548950>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'name': 'Jane', 'height': 1.7, 'gender': 'male'}
这里的不同之处在于对象和类它们存放值的命名空间不同
4.delattr()
用于删除属性
class Person:age = 20def __init__(self,name,height,weight):self.name = nameself.height = heightself.weight = weight p = Person('Adson',1.6,75) print(p.__dict__) #{'name': 'Adson', 'height': 1.6, 'weight': 75} delattr(p,'height') print(p.__dict__) #{'name': 'Adson', 'weight': 75} print(Person.__dict__['age']) #20 delattr(Person,'age') print(Person.__dict__['age']) #KeyError: 'age'
内置类方法
内置的类方法和内置函数之间有着千丝万缕的关系
1.__str__
当我们定义一个类,并实例化一个对象,再对这个对象去print
class A:def __init__(self,name,price,types):self.name = nameself.price = priceself.types = types a = A('AAA',200,'A') print(str(a)) #<__main__.A object at 0x00000000020D7A58>
这里返回了这个对象的内存地址,我们再在A类里面添加一个__str__方法,看一看结果是什么
class A:def __init__(self,name,price,types):self.name = nameself.price = priceself.types = typesdef __str__(self):return 'name = %s,price = %s,types = %s'%(self.name,self.price,self.types) a = A('AAA',200,'A') print(a) #name = AAA,price = 200,types = A
可以这么说我们在每次打印一个对象的时候就是在调用obj.__str__,且__str__方法需要返回一个字符串,当做这个类的描写;当我们使用print这个对象时会打印出__str__方法return出来的字符串
2.__repr__
先说一下repr()方法,它能让我们输入的数据原形毕露
print(repr(1)) #1 print(repr('1')) #'1' print(repr('aaa')) #'aaa' print(repr({'a':1,'b':2})) #{'a': 1, 'b': 2}
和__str__一样我们在定义一个类后去print它实例化的对象,会获得到一个对象的内存地址
class A:def __init__(self,name,price,types):self.name = nameself.price = priceself.types = types a = A('AAA',200,'A') print(repr(a)) #<__main__.A object at 0x00000000024E7A58>
然后我们再在A中添加__repr__方法看一下print的结果
class A:def __init__(self,name,price,types):self.name = nameself.price = priceself.types = typesdef __repr__(self):return 'name = %s,price = %s,types = %s' % (self.name, self.price, self.types) a = A('AAA',200,'A') print(repr(a)) #name = AAA,price = 200,types = A print(a) #name = AAA,price = 200,types = A
因为我们在类中定义了一个__repr__方法,这里我们print对象a的时候就相当于是调用了里面的__repr__方法即a.__repr__
如果一个类中的__str__和__repr__同时存在的话,那么最后的打印结果是什么呢?
class A:def __init__(self,name,price,types):self.name = nameself.price = priceself.types = typesdef __str__(self):return 'str(name = %s,price = %s,types = %s)'%(self.name,self.price,self.types)def __repr__(self):return 'repr(name = %s,price = %s,types = %s)' % (self.name, self.price, self.types) a = A('AAA',200,'A') print(repr(a)) #repr(name = AAA,price = 200,types = A) 即a.__repr__ print('%r'%a) #repr(name = AAA,price = 200,types = A) print(str(a)) #str(name = AAA,price = 200,types = A) 即a.__str__ print('%s'%a) #str(name = AAA,price = 200,types = A) print(a) #str(name = AAA,price = 200,types = A)
如果一个类中有__str__方法,那么它就会先找__str__,没有的话就再找__repr__方法,再没有的话就会找它父类的__str__方法
__str__方法和__repr__方法能够返回该对象一个规范化的信息
3.__len__
我们将一个实例化的对象直接print它的len看一看会出现什么结果
class A:def __init__(self,name,price,types):self.name = nameself.price = priceself.types = types a = A('AAA',200,'A') print(len(a)) #TypeError: object of type 'A' has no len()
结果报错说A少了一个len函数,也就是我们只有在A中加上一个__len__的方法才能去计算长度相关的东西
计算属性的长度:
class A:def __init__(self,name,price,types):self.name = nameself.price = priceself.types = typesdef __len__(self):return len(self.name) a = A('AAA',200,'A') print(len(a)) #3
计算一个列表属性有几个元素:
class A:def __init__(self,goods = []):self.goods = []def __len__(self):return len(self.goods) a = A() print(len(a)) #0 a.goods.append('Banana') a.goods.append('Apple') a.goods.append('Orange') a.goods.append('Pear') print(len(a)) #4
4.__call__
用于打印这个对象的属性
class A:gender = 'male'def __init__(self,name,price,types):self.name = nameself.price = priceself.types = typesdef __call__(self, *args, **kwargs):return self.name,self.price,self.types,self.gender a = A('AAA',200,'A') print(a()) #('AAA', 200, 'A', 'male') print(A('AAA',200,'A')()) #('AAA', 200, 'A', 'male')
5.__eq__
class A:__instance = Falsedef __init__(self,name,age,height):self.name = nameself.age = ageself.height = heightdef __eq__(self, other):if self.name == other.name and self.height == other.height:return Trueelse:return False a1 = A('Jane',20,55) a2 = A('Jane',18,55) print(a1 == a2) #True
6.__hash__
控制对象中的哈希值和另外一个对象的哈希值是否相等
class A:def __init__(self,name,age,height):self.name = nameself.age = ageself.height = heightdef __hash__(self):return hash(self.age + self.height) + hash(self.name) a1 = A('Jane',20,55) a2 = A('Jane',18,55) print(hash(a1)) #-1393240518857837779 print(hash(a2)) #-1393240518857837781
7.__new__
创建一个对象
class A:height = 18def __init__(self):self.name = 'Aane'self.price = 300self.types = 'aaa'def __new__(cls, *args, **kwargs):print('实例化一个对象...')return object.__new__(cls, *args, **kwargs) a = A() #实例化一个对象... print(a.__dict__) #{'name': 'Aane', 'price': 300, 'types': 'aaa'}
单例模式:限制一个类始终只有一个实例,因为一般来讲一个类可以产生无数个对象
在这里我们创建三个对象并打印它们的内存地址可以发现它们是不同的
class A:def __init__(self):self.name = 'aaa' a1 = A() a2 = A() a3 = A() print(a1) #<__main__.A object at 0x00000000025B1D68> print(a2) #<__main__.A object at 0x00000000025CD0F0> print(a3) #<__main__.A object at 0x00000000025CD128>
所以在我们第一次实例化这个类的时候就创建一个实例化的对象,那么我们再一次实例化一个对象的话该如何再去使用之前的实例化对象呢?
class A:__instance = Falsedef __init__(self,name,age):self.name = nameself.age = agedef __new__(cls,*args,**kwargs):if cls.__instance:return cls.__instancecls.__instance = object.__new__(A)return cls.__instance a1 = A('Jogn',33) a2 = A('Jane',35) a3 = A('KKK',55) print(a1) #<__main__.A object at 0x000000000217D198> print(a1.__dict__) #{'name': 'KKK', 'age': 55} print(a2) #<__main__.A object at 0x000000000217D198> print(a2.__dict__) #{'name': 'KKK', 'age': 55} print(a3) #<__main__.A object at 0x000000000217D198> print(a3.__dict__) #{'name': 'KKK', 'age': 55} print(id(a1),id(a2),id(a3)) #41734552 41734552 41734552
8.__del__
析构函数:当对象结束其生命周期,如对象所在的函数已调用完毕时,系统自动执行析构函数,它往往用来做"清理善后"的工作。当我们直接删除一个实例化的对象再去打印它,就会报错告诉我们这个对象已经不存在了
class A:def __init__(self,name,price,types):self.name = nameself.price = priceself.types = types a = A('AAA',200,'A') del a print(a) #NameError: name 'a' is not defined
我们再在A中添加一个__del__方法
class A:def __init__(self,name,price,types):self.name = nameself.price = priceself.types = typesdef __del__(self):print('这个对象%s已被删除!' % self.name)del self a = A('AAA',200,'A') del a #这个对象AAA已被删除! 这里相当于调用了a.__dict__ print(a) #NameError: name 'a' is not defined
8.__getitem__
模拟字典的方式来拿值
class A:gender = 'male'def __init__(self,name,price,types):self.name = nameself.price = priceself.types = typesdef __getitem__(self, item):if hasattr(self,item):return getattr(self,item)return '没有找到这个值!' a = A('AAA',200,'A') print(a['name']) #AAA print(a['price']) #200 print(a['types']) #A print(a['gender']) #male print(a['sex']) #没有找到这个值!
9.__setitem__
模拟字典的方式来设值
class A:def __init__(self,name,price,types):self.name = nameself.price = priceself.types = typesdef __setitem__(self,key,value): #重新设定一个新的值self.__dict__['key'] = value a = A('AAA',200,'A') print(a.__dict__) #{'name': 'AAA', 'price': 200, 'types': 'A'} a.__dict__['name'] = 'BBB' a.__dict__['price'] = 300 a.__dict__['types'] = 'C' a.__dict__['gender'] = 'male' #增加了一个新的属性gender print(a.__dict__) #{'name': 'BBB', 'price': 300, 'types': 'C', 'gender': 'male'}
10.__delitem__
模拟字典的方式来删除
class A:gender = 'male'def __init__(self,name,price,types):self.name = nameself.price = priceself.types = typesdef __delitem__(self, key):print('%s已删除!'%key)del self.__dict__[key] a = A('AAA',200,'A') del a['name'] #name已删除! del a['price'] #price已删除! print(a.__dict__) #{'types': 'A'}
问题总结
1.有很多对象,它们的姓名和性别相同但是年龄不同,如何这种情况的对象去重?
class A:def __init__(self,name,sex,age):self.name = nameself.sex = sexself.age = agedef __eq__(self, other):if self.name == other.name and self.sex == other.sex:return Truereturn Falsedef __hash__(self):return hash(self.name+self.sex) a = A('Json','male',26) b = A('Json','male',30) print(set((a,b))) #set()依赖对象的 __eq__和__hash__ {<__main__.A object at 0x0000000002761DD8>}
2.扑克牌问题
import json from collections import namedtuple Card = namedtuple('Card',['rank','suit']) #rank牌面的大小 suit牌面的花色 class FrenchDeck:ranks = [str(n) for n in range(2,11)] + list('JQKA')suits = ['红心','方块','梅花','黑桃']def __init__(self):self._cards = [Card(rank,suit) for rank in FrenchDeck.ranks for suit in FrenchDeck.suits]def __len__(self):return len(self._cards)def __getitem__(self, item):return self._cards[item]def __setitem__(self,key,value):self._cards[key] = valuedef __str__(self):return json.dumps(self._cards,ensure_ascii=False)deck = FrenchDeck() print(deck[10]) #Card(rank='4', suit='梅花') from random import choice print(choice(deck)) #Card(rank='3', suit='方块') print(choice(deck)) #Card(rank='9', suit='方块') from random import shuffle shuffle(deck) print(deck[10]) #Card(rank='2', suit='方块') print(deck) #打印所有牌色 print(deck[:5]) #[Card(rank='6', suit='梅花'), Card(rank='3', suit='方块'), Card(rank='10', suit='红心'), #Card(rank='9', suit='红心'), Card(rank='4', suit='方块')]
转载于:https://www.cnblogs.com/Fantac/p/11495039.html
Python学习日记(二十七) 反射和几个内置函数相关推荐
- python求最小值不能使用min和sotred_python基础——内置函数
python基础--内置函数 一.内置函数(python3.x) 内置参数详解官方文档: https://docs.python.org/3/library/functions.html?highl ...
- python 创建空的numpy数组_数据分析-NumPy内置函数创建数组
微信公众号:yale记 关注可了解更多的教程问题或建议,请公众号留言. 背景介绍 今天学习使用numpy的内置函数arange().ones().zeros().linspace() 等内置函数创建数 ...
- python __call__一般用在哪些地方_Python __call__内置函数的作用和用法
开学了进入了实验室,需要协助大师兄做事,主要是OpenStack中的代码解析,但是涉及很多python高级用法,一时间有点麻烦,在做项目的同时慢慢更新博客.这次先写一下__call__的用法,因为经常 ...
- python常用函数-Python小白必备的8个最常用的内置函数(推荐)
Python给我们内置了大量功能函数,官方文档上列出了69个,有些是我们是平时开发中经常遇到的,也有一些函数很少被用到,这里列举被开发者使用最频繁的8个函数以及他们的详细用法 print() prin ...
- python3的输出函数_教女朋友学Python3(二)简单的输入输出及内置函数查看
原创...
这是第二天了,工作之余和女朋友一起学Python3,代码都是她敲的,有点辣眼睛,仅做参考. 1.题目:输入"姓名",输出"你好,姓名" 步骤: file> ...
- python必背代码-Python小白必备的8个最常用的内置函数(推荐)
Python给我们内置了大量功能函数,官方文档上列出了69个,有些是我们是平时开发中经常遇到的,也有一些函数很少被用到,这里列举被开发者使用最频繁的8个函数以及他们的详细用法 print() prin ...
- Python学习日记(二十五) 接口类、抽象类、多态
接口类 继承有两种用途:继承基类的方法,并且做出自己的改变或扩展(代码重用)和声明某个子类兼容于某基类,定义一个接口类interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子 ...
- [转载] python学习笔记2--操作符,数据类型和内置功能
参考链接: Python中的Inplace运算符| 1(iadd(),isub(),iconcat()-) 什么是操作符? 简单的回答可以使用表达式4 + 5等于9,在这里4和5被称为操作数,+被称为 ...
- JavaWeb学习总结(二)——JSP中的九个内置对象
一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...
最新文章
- 【CyberSecurityLearning 36】靶场环境搭建(ubuntu系统安装优化及vulhub安装)
- PPR 搜索里max hit不起作用
- 2016/11/10 kettle概述
- MySQL(9)主从复制和读写分离
- React 的慢与快:优化 React 应用实战
- C语言给考场编号,求:用C设计考场的编排,生成准考证号基本要求:br/(1)用 爱问知识人...
- python决策树画图_利用python用iris做一个决策树的可视化更好的理解机器学习!...
- 1.第一本 docker 书 --- 简介
- cmake的安装与基本使用
- linux网络设备驱动之dm9000驱动源码框架解析
- 中科院计算机所沈阳待遇怎么样,中科院沈阳计算技术研究所计算机技术怎么样...
- Holding Two
- pandas写入excel指定行_使用pandas操作excel
- python_pdf常规使用
- oracle是java代码块,Oracle中施行java代码
- RK3588平台开发系列讲解(DisplayPort篇)DP相关模式说明
- 有一种蓝,是神往,是心醉,是心伤
- nbiot电信云北向开发---基于LiteNAdemo_https例程
- Android Studio Chipmunk 现已发布
- SpringBoot学习-part69安全-权限控制注销