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'

内置类方法

猜你喜欢

转载自www.cnblogs.com/Fantac/p/11495039.html