博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
面向对象----反射
阅读量:7123 次
发布时间:2019-06-28

本文共 5866 字,大约阅读时间需要 19 分钟。

一,isinstance和issubclass

isinstance(obj,cls)检查obj是否是类cls的对象

issubclass(sub,super)检查sub类是否是super类的子类

# class A:#     pass# class B(A):pass# a=A()# b=B()# print(issubclass(B,A))      #判断一个类是否为一个类的子类# print(isinstance(a,A))      #判断对象是否为类的对象# print(isinstance(b,A))

二,反射

1,什么是反射?

主要是指程序可以访问、检测、和修改它本身状态或行为的一种能力。

2,python面向对象中的反射:通过字符串的形式操作对象相关的属性(就是用字符串类型的名字去操作变量),python中一切事物皆对象(都可以使用反射)

四个实现反射的函数

1,getattr,hasattr(一般一起用)

# class A:pass# class B(A):pass# a = A()# print(isinstance(a,A))# print(issubclass(B,A))# print(issubclass(A,B))# 反射 : 是用字符串类型的名字 去操作 变量# name = 1# eval('print(name)')  # 安全隐患# 反射 就没有安全问题# 反射 : 是用字符串类型的名字 去操作 变量# 反射对象中的属性和方法   # hasattr getattr setattr delattr# class A:#     def func(self):#         print('in func')## a = A()# a.name = 'alex'# a.age = 63# # 反射对象的属性# ret = getattr(a,'name')  # 通过变量名的字符串形式取到的值# print(ret)# print(a.__dict__)# 变量名 = input('>>>')   # func# print(getattr(a,变量名))# print(a.__dict__[变量名])## # 反射对象的方法# a.func()# ret = getattr(a,'func')# ret()## class A:#     price = 20#     @classmethod#     def func(cls):#         print('in func')# # 反射类的属性# # A.price# print(getattr(A,'price'))## # 反射类的方法 :classmethod staticmethod# # A.func()# if hasattr(A,'func'):#     getattr(A,'func')()#模块# import my# 反射模块的属性# print(my.day)# print(getattr(my,'day'))# 反射模块的方法# getattr(my,'wahaha')()# 内置模块也能用# time# asctime# import time# print(getattr(time,'time')())# print(getattr(time,'asctime')())# def qqxing():#     print('qqxing')# year = 2018# import sys# # print(sys.modules['__main__'].year)# # 反射自己模块中的变量# # print(getattr(sys.modules['__main__'],'year'))## # 反射自己模块中的函数# # getattr(sys.modules['__main__'],'qqxing')()# 变量名 = input('>>>')# print(getattr(sys.modules[__name__],变量名))# 反射的函数有参数# print(time.strftime('%Y-%m-%d %H:%M:S'))# print(getattr(time,'strftime')('%Y-%m-%d %H:%M:S'))# 一个模块中的类能反射得到# import my# print(getattr(my,'C')())# if hasattr(my,'name'):#     getattr(my,'name')
用法演示

2,setattr设置修改变量

# class A:#     pass# a=A()# setattr(a,"name","nezha")# setattr(A,"name","fg")# print(a.name)# print(A.name)

3,delattr删除

# 删除  delattr# delattr(a,"name")# print(a.name)

三,双下方法

1,__str__和__repr__

# obj.__str__  str(obj)# obj.__repr__ repr(obj)# class Teacher:#     def __init__(self,name,salary):#         self.name = name#         self.salary = salary#     def __str__(self):#         return "Teacher's object :%s"%self.name#     def __repr__(self):#         return str(self.__dict__)#     def func(self):#         return 'wahaha'# nezha = Teacher('哪吒',250)# print(nezha)  # 打印一个对象的时候,就是调用a.__str__# print(repr(nezha))# print('>>> %r'%nezha)#a.__str__ --> object# object  里有一个__str__,一旦被调用,就返回调用这个方法的对象的内存地址# l = [1,2,3,4,5]   # 实例化 实例化了一个列表类的对象# print(l)# %s str()  直接打印 实际上都是走的__str__# %r repr()  实际上都是走的__repr__# repr 是str的备胎,但str不能做repr的备胎# print(obj)/'%s'%obj/str(obj)的时候,实际上是内部调用了obj.__str__方法,如果str方法有,那么他返回的必定是一个字符串# 如果没有__str__方法,会先找本类中的__repr__方法,再没有再找父类中的__str__。# repr(),只会找__repr__,如果没有找父类的
View Code

2,__len__

# 内置的方法有很多# 不一定全都在object中# class Classes:#     def __init__(self,name):#         self.name = name#         self.student = []#     def __len__(self):#         return len(self.student)#     def __str__(self):#         return 'classes'# py_s9= Classes('python全栈9期')# py_s9.student.append('二哥')# py_s9.student.append('泰哥')# print(len(py_s9))# print(py_s9)
View Code

3,__del__

析构方法,当对象在内存中被释放,自动触发执行。

此方法一般无需定义,因为python是一门高级语言,析构函数的调用是由解释器自动触发。

# class A:#     def __del__(self):#         print("爸爸执行了")# a=A()# del a# print(">>>>")

4,__call__

对象后面加括号,触发执行。

构造方法的执行是由创建对象触发的,即:对象=类名();而对于__call__方法的执行是由对象后加括号触发的,即:对象()或者类()()

class A:    def __init__(self, name):        self.name = name    def __call__(self):        '''        打印这个对象中的所有属性        :return:        '''        for k in self.__dict__:            print(k, self.__dict__[k])b= A('alex')()   #执行__call__#name alexclass A:    def __init__(self):        print("sd")    def __call__(self):        print("ahi")a=A()a()A()()#结果# sd# ahi# sd# ahi
View Code

 5,item系列

getitem  /  setitem  /delitem# class Foo:#     def __init__(self,name,age):#         self.name=name#         self.age=age#     def __getitem__(self, item):#         if hasattr(self, item):#             return self.__dict__[item]      #查#     def __setitem__(self, key, value):#         self.__dict__[key]=value          #增 改#     def __delitem__(self, key):#         del self.__dict__[key]        #删# f=Foo("hi",6)# f["age"]=12# print(f["age"])# f["gao"]=1.77# print(f["gao"])# del f["gao"]         #通过自己实现的(__delitem__方法)# del f.gao          #object 原生支持的# print(f["gao"])
View Code

6,__new__(构造方法:创建一个对象)

# class A:#     def __init__(self):#         self.s=5#         print("2")#     def __new__(cls, *args, **kwargs):#         print("1")#         return object.__new__(A)# a1=A()# a2=A()# print(a1.s)
View Code
# class A:#     __instance=False#     def __init__(self,name,age):#         self.name=name#         self.age=age#     def __new__(cls, *args, **kwargs):#         if cls.__instance:#             return cls.__instance#         cls.__instance=object.__new__(cls)#         return cls.__instance# egon=A("egg",45)# egon.cloth="棍子"# egon.hi="df"# print(egon.__dict__)# na=A("gh",23)# print(na.__dict__)# print(egon.__dict__)只会创建一个对象,新的会覆盖旧的对象
单例模式

7,__hash__

# class A:#     def __init__(self,name,sex):#         self.name=name#         self.sex=sex#     def __hash__(self):#         return hash(self.name+self.sex)# a=A("nazha","ni")# b=A("nazha","ni")# print(hash(a))# print(hash(b))有__hash__方法得到的哈希值是参数内容的哈希值。没有__hash__方法得到的哈希值是对象的哈希值。
View Code

8,__eq__

class A:    def __init__(self,name):        self.name=name    def __eq__(self, other):        if self.__dict__ == other.__dict__:            return True        else:            return Falseob1=A("alex")oa1=A("alex")print(ob1==oa1)__eq__比较内容是否一致
View Code

 注:默认比较内存地址

转载于:https://www.cnblogs.com/glf1160/p/8330220.html

你可能感兴趣的文章
DOM何时Ready
查看>>
常用正则表达式
查看>>
【SICP练习】46 练习2.5
查看>>
Windows Server 2016 配置指南 之 安装 phpMyAdmin
查看>>
分析iOS Crash文件:符号化iOS Crash文件的3种方法
查看>>
[LeetCode]129.Sum Root to Leaf Numbers
查看>>
ganglia mtu metric BUG? on CentOS 6.x x64
查看>>
100的阶层真的算不出来吗?
查看>>
Python-列表和元祖
查看>>
F - Maximum GCD——(UVA 11827)
查看>>
MySQL-Transfer2.3发布
查看>>
BottomNavigationView解决三个限制记录
查看>>
Android拖拽、回弹布局
查看>>
webpack
查看>>
js函数
查看>>
access token
查看>>
爬虫神器pyppeteer,对 js 加密降维打击
查看>>
吃鸡数据不完全分析
查看>>
iOS上下联动框架(Swift)
查看>>
Android RxJava之变换操作符(三)
查看>>