1.反射

hasattr getattr delattr setattr

优点:事先定义好接口,接口只有在被完成后才能真正执行,这实现了即插即用,这其实是一种“后期绑定”,即先定义好接口,

然后是再去实现具体的功能

print(hasattr(p, 'age'))  # True 是否有属性 判断

print(getattr(p, 'name', '没有找到该参数'))  # get属性值
print(getattr(p, 'name1', 'False')) # False setattr(p, 'name', 'sb') # 设置属性
print(p.__dict__) delattr(p, 'name') # 删除属性
print(p.__dict__)
setattr(p, 'func', lambda x: x + 1)
setattr(p, 'func1', lambda self: self.name + " sb")
print(p.__dict__)
print(p.func(100)) # 添加函数属性
setattr(p, 'name', 'wangwu')
print(p.func1(p))
# 反射应用场景
class FtpClient:
#'ftp客户端,但是还么有实现具体的功能'
def __init__(self, addr):
print('正在连接服务器[%s]' % addr)
self.addr = addr from module import FtpClient
f1 = FtpClient('192.168.1.1')
if hasattr(f1, 'get'): # 判断f1是否有get方法 如果没有 就执行else语句
func_get = getattr(f1, 'get')
func_get()
else:
print('---->不存在此方法')
print('处理其他的逻辑')

2.动态导入模块

# 动态导入模块
module__test = __import__('macboy.wsgi') # 此处就是macboy位置
print(module__test) # <module 'macboy' from 'C:\\Disk_D\\pycharm_stu\\macboy\\macboy'> import importlib m = importlib.import_module('macboy.wsgi') # 此处是macboy.wsgi位置
print(m) # <module 'macboy.wsgi' from 'C:\\Disk_D\\pycharm_stu\\macboy\\macboy\\wsgi.py'>

3.类attr属性 __gerattr__ __setattr__ __delattr__ __getattribute__

# 双下划线开头的类属性 obj.属性 触发
class Foo:
def __init__(self, name):
self.name = name # 属性不存在时 被触发 比较常用
def __getattr__(self, item):
return "%s属性不存在" % (item) # 添加属性时 被触发
def __setattr__(self, key, value):
self.__dict__[key] = str(value) # 删除属性时 被触发
def __delattr__(self, item):
self.__dict__.pop(item) a = Foo('wangwu')
print(a.name)
print(a.ww) # ww属性不存在
# print(a.__dict__) a.age = 10
a.gender = 'man'
# print(a.__dict__)
print(dir(Foo))
# print(Foo.__dict__) print(a.gender) # "man"
print(a.age) #
# print(a.__dict__) del a.gender
del a.age print(a.gender) # gender属性不存在
print(a.age) # age属性不存在 # __getattribute 和 __getarr__ 不管找不找的到,都会执行 先前面执行后面后执行 不管是否有偶异常 __getattribute都执行
# 当__getattribute抛出一异常 小弟__getarr__接受到 处理异常
class Foo:
    def __init__(self, name):
        self.name = name     def __getattr__(self, item):
        return "你找的%s属性不存在" % (item)     def __getattribute__(self, item):
        print("执行的是__getattribute")
        raise AttributeError("抛出异常") f1 = Foo('fdsf')
print(f1.fdd)

4.继承方式包装

包装:python为大家提供了标准数据类型,以及丰富的内置方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增/改写方法,这就用到了我们刚学的继承/派生知识(其他的标准类型均可以通过下面的方式进行二次加工)

#  二次加工标准类型(包装)
class List(list):
def append(self, item):
if isinstance(item, str):
super().append(item)
else:
print("只能加字符串") l = List("helloworld")
l.append("")
l.append(111) # 只能加字符串 print(l)

5.组合方式授权

授权:授权是包装的一个特性, 包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原有产品的功能。其它的则保持原样。授权的过程,即是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。

实现授权的关键点就是覆盖__getattr__方法

# 组合方式授权
import time
class Open:
def __init__(self, filename, mode='r', encoding='utf-8'):
self.file = open(filename, mode, encoding=encoding)
self.mode = mode
self.encoding = encoding def write(self, line):
t = time.strftime("%Y-%m-%d %X")
self.file.write('%s %s' % (t, line)) def __getattr__(self, item):
# >>> getattr(list,"append")
# <method 'append' of 'list' objects>
return getattr(self.file, item) # file中执行item方法 f1 = Open('a.txt', 'w+')
print(f1.__dict__)
print(dir(f1.file)) f1.write('内存空间不足\n')
f1.write('服务器超载\n')
f1.seek(0)
print(f1.read())

python 反射 动态导入模块 类attr属性的更多相关文章

  1. Python importlib(动态导入模块)

    使用 Python importlib(动态导入模块) 可以将字符串型的模块名导入 示例: import importlib module = 'module name' # 字符串型模块名 test ...

  2. python importlib动态导入模块

    一般而言,当我们需要某些功能的模块时(无论是内置模块或自定义功能的模块),可以通过import module 或者 from * import module的方式导入,这属于静态导入,很容易理解. 而 ...

  3. python_反射:动态导入模块

    官方推荐方法: test_mod.py def hi(): print('Hi') test.py import importlib q = importlib.import_module('test ...

  4. python中动态导入模块

    当导入的模块不存在时,就会报ImportError错误,为了避免这种错误可以备选其他的模块或者希望优先使用某个模块或包,可以使用try...except...导入模块或包的方式. 例如: Python ...

  5. java利用反射动态获取实体类的属性值

    直接贴代码吧,有需要的话,可以根据自己的需要修改部分代码: public BigDecimal getByAttributeName(ThmdGwqriR thmdGwqriR, String att ...

  6. python动态导入模块——importlib

    当在写代码时,我们希望能够根据传入的选项设置,如args.model来确定要导入使用的是哪个model.py文件,而不是一股脑地导入 这种时候就需要用上python的动态导入模块 比如此时文件结构为: ...

  7. Python 实现接口类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)

    实现接口类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...

  8. python面向对象反射-框架原理-动态导入-元类-自定义类-单例模式-项目的生命周期-05

    反射 reflect 反射(reflect)其实是反省,自省的意思 反省:指的是一个对象应该具备可以检测.修改.增加自身属性的能力 反射:通过字符串获取对象或者类的属性,进行操作 设计框架时需要通过反 ...

  9. Python 实现抽象类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)

    实现抽象类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...

随机推荐

  1. 01背包-记忆化搜索到成型的DP

    记忆化搜索 #include<bits/stdc++.h> using namespace std; typedef long long ll; int n,W; int dp[105][ ...

  2. ftpClient.retrieveFileStream导致FTPClient的后面操作失败

    问题代码: FTPFile[] fs = ftpClient.listFiles(); for (FTPFile ff : fs) { if (ff.getName().equals(fileName ...

  3. 微信 oauth 登录 ,回调两次,一个坑,记录一下。

    在做微信某个功能的时候,大致需求是:静默授权,得到openId ,然后拿着openId调用接口,判断是否关注.如果是关注的,则发放礼券.每个我网站的会员只会发放一次礼券.如果第二次则会提示已领取过礼券 ...

  4. 删除数据库的数据后让id从1开始算

    delete from t_AttendanceRecorddbcc checkident('t_AttendanceRecord',reseed,0) truncate table  表名称

  5. Spring Boot Starters是什么?

    版权声明:该文转自: http://www.nosuchfield.com/2017/10/15/Spring-Boot-Starters/.版权归原创作者,在此对原作者的付出表示感谢! starte ...

  6. 解决图片浮动调节不了的问题(使用vertical-align属性)

    vertical-align: middle; vertical-align 属性设置元素的垂直对齐方式. baseline  默认.元素放置在父元素的基线上.sub 垂直对齐文本的下标.super ...

  7. 1-1、create-react-app 配置 mobx

    1.用npx create-react-app my-app安装项目 2.cd my-app 3.执行 npm  run eject  让配置文件可见 4.npm install --saveDev ...

  8. java并发编程(10)Fork/Join

    Fork/Join JAVA7中出现的Fork/Join,类似于分布式文件系统hadoop的mapreduce思想,就是将任务分割,再分割,直到分割到满足条件 为了便于理解:编程逻辑可以借用 递归的思 ...

  9. Delphi下OpenGL2d绘图(04)-画四边形

    一.前言 画四边形基本上与前几遍文字代码是相同.区别在于glBegin()的参数“GL_QUADS”.绘制的框架代码可以使用 Delphi下OpenGL2d绘图(01)-初始化 中的代码.修改的部份为 ...

  10. 联想G480安装固态硬盘过程

    联想G480安装固态硬盘过程  百度上面图文并茂: https://jingyan.baidu.com/article/e2284b2b68eaf6e2e6118de1.html