python3基础-反射、内置attr属性、动态导入的问题

一 反射

反射指的是通过字符串来操作对象的属性

class People:
    nationality='china'
    def __init__(self,name):
        self.name=name

    def eat(self):
        print("%s吃水果"%self.name)


p1 = People('苏苏')

#hasattr(object,name)
print(hasattr(p1,'name'))   #按字符串‘name’ 判断有无属性p1.name   返回True
print(hasattr(p1,'eat'))  #按字符串‘eat’ 判断有无属性p1.eat

#getattr(object,'name',default)
print(getattr(p1,'name',None))  #等同于p1.name  不存在该属性则返回默认值none ;
func = getattr(p1,'eat')  #p1.eat
func() #则输出的是 susu 吃水果

#setattr(object,'name',value)
setattr(p1,'name','SB') #==P1.name='SB'  直接修改属性
print(getattr(p1,'name',None)) #则输出的是 SB
#新增一个属性
setattr(p1,'age',28)
print(p1.__dict__)  #输出的是{'name': 'SB', 'age': 28}

#delattr(object,'name')
delattr(p1,'name')
print(getattr(p1,'name',None)) #则输出的是 None

基于反射可以灵活地操作对象的属性,比如将用户交互的结果反射到具体的功能执行

二 内置attr属性

#注意: __getattr__  __delattr__  __setattr__ 触发条件是实例化后才能触发
class People:
    nationality='china'
    def __init__(self,name):
        self.name=name

    # __getattr__:当使用点号获取实例属性时,如果属性不存在就自动调用__getattr__方法
    def __getattr__(self, item):
        print('__getattr__:调用一个不存在的对象属性时候,执行',item)

    #删除属性的时候会触发
    def __delattr__(self, item):
        print('__delattr__删除一个属性时候,执行',item)


    def __setattr__(self, key, value):
        print('__setattr__修改/添加一个属性时候')
        #self.key = value
        #RecursionError: maximum recursion depth exceeded while calling a Python object
        #因为这个也是在设置一个属性,当设置这个属性的时候,也会触发__setattr__,这样就会一直循环,最后报错,所有使用self.__dict__[key] = value操作
        self.__dict__[key]=value

p1 = People('小苏') #设置一个属性操作的时候,执行__setattr__; __init__中的self.name 传递给key    name 传递给value
print(p1.name)
print(getattr(p1,'哈哈哈')) #属性不存在就自动调用__getattr__方法
print(getattr(p1,'name')) #属性存在,则就返回属性值
p1.ssssss #属性不存在就自动调用__getattr__方法

print(p1.__dict__)
p1.age=18
print(p1.__dict__)

del p1.name  #删除存在的属性,会触发__delattr__
del p1.height#删除不存在的属性,也会触发__delattr__

以上代码执行

__setattr__修改/添加一个属性时候
小苏
__getattr__:调用一个不存在的对象属性时候,执行 哈哈哈
None
小苏
__getattr__:调用一个不存在的对象属性时候,执行 ssssss
{'name': '小苏'}
__setattr__修改/添加一个属性时候
{'name': '小苏', 'age': 18}
__delattr__删除一个属性时候,执行 name
__delattr__删除一个属性时候,执行 height

三 动态导入

a=1
print("111",a)
def dev1():
    print("dev.py")
    return  1
dev.py文件
def test1():
    return 'test1'


def _test2():
    return 'test2'
m1目录下的test文件
#-src
#   |-----dev.py
#   |-----动态导入模块.py
#   |-----m1目录
#               |-----test.py
print('----方法1')
from m1 import  test
test.test1()

#方法2
#调用m1 目录下 test文件里面的test1
print('----方法2')
t1 = __import__('m1.test')
print(t1)
print(t1.test.test1())

#方法3
#调用相同目录下的dev文件
print('----方法3')
t1 = __import__('dev')
print(t1)
print(t1.dev1())

#方法4
#调用m1 目录下 所有的文件
print('----方法4')
from  m1.test import *
print(test1())
#_test2()  调用模块 函数单下划线开头就无法调用成功

#方法5
#调用m1 目录下 test
print('----方法5')
import importlib
t1 = importlib.import_module('m1.test')
print(t1)
print(t1.test1())

以上代码执行结果如下:

----方法1
test1
----方法2
<module 'm1' (namespace)>
test1
----方法3
111 1
<module 'dev' from 'D:\\pyAuto\\pythonDay\\pythonbase\\类\\dev.py'>
dev.py
1
----方法4
test1
----方法5
<module 'm1.test' from 'D:\\pyAuto\\pythonDay\\pythonbase\\类\\m1\\test.py'>
test1

 

 

 

posted @ 2019-11-13 20:23  槑槑DE  阅读(257)  评论(0编辑  收藏  举报