首页 / PYTHON / python(八):反射
python(八):反射
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python(八):反射,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5026字,纯文字阅读大概需要8分钟。
内容图文
![python(八):反射](/upload/InfoBanner/zyjiaocheng/1123/eaad82f7ea634cc28f7e3083b8e096dc.jpg)
反射机制是通过python3内置的hasattr、getattr、setattr来实现的。即根据变量名的字符串形式来获取变量名的属性或方法。
一、通过反射查看已知对象的属性和方法
getattr(object, name[, default]) -> value
Get a named attribute from an object; getattr(x, ‘y‘) is equivalent to x.y. When a default argument is given, it is returned when the attribute doesn‘t exist; without it, an exception is raised in that case.
getattr接收三个参数:对象,对象的属性或方法,以及未获取到时的默认返回值。
class MyClass(object): country = "China"def__init__(self, name, age): self.name = name self.age = age self._gender = None def hello(self): print("I‘m {}, {}.".format(self.name, self.age)) def gender(self, gender): self._gender = gender print(self._gender) print(getattr(MyClass, "country")) # 获取对象的静态属性 my = MyClass("Li", 24) print(getattr(my, "name")) # 获取实例的变量(属性) getattr(my, "hello")() # 获取并执行实例的方法 getattr(my, "gender")("female") # 传入参数
二、通过反射获取模块的方法
1.访问当前模块的对象。
def func(): func.name = "Li" func.age = 24 print("I‘m {}, {}.".format(func.name, func.age)) if__name__ == ‘__main__‘: import sys # 需要引入sys模块,用sys.modelus["__main__"]访问当前模块的内存地址 getattr(sys.modules["__main__"], "func")() # 从模块中获取属性print(getattr(func, "name"))
2.访问其它模块的对象。
将上面的代码保存到test1.py文件中,在test2.py中导入test1.py,同样可以访问MyClass类。
import test1 if __name__ == ‘__main__‘: MyClass = getattr(test1, "MyClass") # 这里也可以用sys.modules["test1"]来替代test1print(MyClass.country) my = MyClass("Li", 24) print(getattr(my, "name")) # 获取实例的变量(属性) getattr(my, "hello")() # 获取并执行实例的方法 getattr(my, "gender")("female") # 传入参数
三、__import__和importlib.import_module
python3提供了一个特殊的方法:__import__(字符串参数)。__import__()方法会根据参数,动态的导入同名的模块。它的功能和getattr相似。
将test2.py中的代码改为下面两行,即可实现同样的功能。
module = __import__("test1") fun = getattr(module, "func")()
或者这样写:
import importlib module = importlib.import_module("test1") fun = getattr(module, "func")()
它们都是根据模块名来访问该模块的内存空间,从而获取全局变量、函数或者类等对象。
来看一段文档介绍:
Docstring:
__import__(name, globals=None, locals=None, fromlist=(), level=0) -> module
Import a module. Because this function is meant for use by the Python interpreter and not for general use,
it is better to use importlib.import_module() to programmatically import a module.
# 导入模块应该用importlib.import_module(),__import__是提供给Python解释器使用的。
# globals和locals、level参数可以忽略。
The fromlist should be a list of names to emulate ``from name import ...‘‘, or an empty list to emulate ``import name‘‘.
When importing a module from a package, note that __import__(‘A.B‘, ...) returns package A when fromlist is empty, but its submodule B when fromlist is not empty.
# fromlist是a list of names blabla。但是试了几次,好像只能用True来设置,其它不起作用
module = __import__("test1", ) # 它相当于import test1 # module = __import__("test.person", fromlist=True) # 它相当于from test import person # 从模块中导入py文件,test是一个package,包含__init__.py和person.py # person.py中包含MyClass类 Myclass = getattr(module, "MyClass") my = Myclass("Li", 24) my.hello()
importlib的用法也相似。
import importlib # module = importlib.import_module("test1") # import test1 # module = importlib.import_module("test.person", package=True) # from test import person module = importlib.import_module("test_outer.test.person", package=True) # from test_outer.test import person Myclass = getattr(module, "MyClass") my = Myclass("Li", 24) my.hello()
四、例子
1.遍历模块查找所需函数。
# 文件夹 test - __init__.py - drink.py # 定义一个drink函数,打印"I‘m drinking." - person.py - say.py # 同drink.py - sleep.py # 同drink.py
person.py
import os import importlib class Person: def __init__ (self, name): self.name = name self.modules = self.py_list() def py_list(self): pys = os.listdir(os.path.dirname(__file__)) modules = [] for py in pys: if py.endswith(".py") andnot py.startswith("__"): modules.append(importlib.import_module(py.split(".")[0])) # 将多个模块全部导入到一个list中 return modules def action(self): while True: imp = input("小明 >>> ") fun = None for module in self.modules: # 遍历查询module,查找imp函数 if hasattr(module, imp): fun = getattr(module, imp) breakif fun: fun() else: print("Order isn‘t correct.") if__name__ == ‘__main__‘: per = Person("Li") per.action()
2.动态导入模块
当然,也可以根据模块名和对象名,来获取相应的模块,并调用相应的方法。从而不必将所有的模块都导入进来。
import importlib class Person: def __init__ (self, name): self.name = name def action(self): while True: imp = input("小明 >>> ") try: module, fun = imp.split("/") module = importlib.import_module(module,) if hasattr(module, fun): getattr(module, fun)() else: print("Order isn‘t correct.") except: print("input not correct.") if__name__ == ‘__main__‘: per = Person("Li") per.action() # 需要输入sleep/sleep 或者drink/drink
3.setattr的使用
import importlib class Person: def __init__ (self, name): self.name = name def sleep(self): getattr(importlib.import_module("sleep"), "sleep")() def drink(self): getattr(importlib.import_module("drink"), "drink")() def fun(self, action): if hasattr(self, action): getattr(self, action) else: setattr(self, action, self.error) # 设置aciton的函数,当然可以在上面的getattr的default关键字中设置 getattr(self, action)() # 调用action的函数 def error(self): print("error.") if__name__ == ‘__main__‘: per = Person("Li") per.fun("wth")
原文:https://www.cnblogs.com/kuaizifeng/p/9092057.html
内容总结
以上是互联网集市为您收集整理的python(八):反射全部内容,希望文章能够帮你解决python(八):反射所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。