Python学习日记(二十七) 反射和几个内置函数

Posted fantac

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 = 20
    def __init__(self,name,height,weight):
        self.name = name
        self.height = height
        self.weight = weight
    def 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:
    @classmethod
    def 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

然后通过我的模块反射模块的变量

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!!!)

然后通过我的模块反射模块方法

import pyfile
ret = getattr(pyfile,fuc)
print(ret)                             #<function fuc at 0x0000000002498D08>
ret()                                  #abc123aaa!!!
getattr(pyfile,fuc)()                #abc123aaa!!!

(7)反射模块的类

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 = 20
    def __init__(self,name,height,weight):
        self.name = name
        self.height = height
        self.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 = 20
    def __init__(self,name,height,weight):
        self.name = name
        self.height = height
        self.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‘

 

内置类方法

 

以上是关于Python学习日记(二十七) 反射和几个内置函数的主要内容,如果未能解决你的问题,请参考以下文章

第二十五章 面向对象------封装内置函数反射动态导入

Python 基础第二十三天(反射)

python全栈开发第十七篇面向对象反射和内置方法

机器学习100天(二十七):027 Python中的函数和类

机器学习100天(二十七):027 Python中的函数和类

机器学习100天(二十七):027 Python中的函数和类