一个关于 Python 反射运用的问题

2021-01-15 18:51:02 +08:00
 dwadewyp

新建一个 python 的 package,在 package 中创建了一个 Animal.py 的文件,并在 Animal.py 文件中定义了一个 Animal 的类;

------Animal.py-------

	class Animal:
	    def __init__(self, name=None):
	        self.name = name

	    def introduce(self):
	        pass

与此同时在 package 下面,创建了 Dog.py,Cat.py,分别在文件中定义了 Dog,Cat 子类(均继承 Animal),并实现了 introduce 方法

-----Dog.py--------

	from animal.animal import Animal

	class Dog(Animal):

	    def introduce(self):
	        print("i am a dog")

----Cat.py------

	from animal.animal import Animal

	class Cat(Animal):
	    def introduce(self):
	        print("i am a cat")


2450 次点击
所在节点    Python
15 条回复
gwy15
2021-01-15 18:59:19 +08:00
Animal.__subclasses__()
weyou
2021-01-15 19:08:30 +08:00
@gwy15
不事先 import 子类的文件,__subclasses__不会有内容
BBrother
2021-01-15 19:12:26 +08:00
dwadewyp
2021-01-15 19:21:31 +08:00
@BBrother 注意是需要在不同的文件下面的哦~~~
RickyHao
2021-01-15 19:26:11 +08:00
你不 import,那这代码就相当于不存在吧?
实在不行,规定个文件夹,启动的时候自动 import 文件夹下的所有代码文件
xchaoinfo
2021-01-15 19:29:22 +08:00
不引入,不实例化,ast 了解下
maocat
2021-01-15 19:29:43 +08:00
我懂题主的意思,a.py, b.py, c.py 3 个 py 文件,分别有 class A,class B(A), class C(A),比如直接运行 a.py 是不能够获取__subclasses__,因为 b.pyc.py 不在 runtime 中,可以试一试 sys.path.append(PATH)
dwadewyp
2021-01-16 15:09:06 +08:00
@gwy15 @BBrother __subclasses__ 是限定在基类和子类在统一文件下, 这个题有个限定条件就是,每个子类在不同的文件中, 并且,需要在这个 animal package 外,创建一个类似 test.py 来进行处理
dwadewyp
2021-01-16 15:10:53 +08:00
@BBrother 亲测 元类在 package 外层 也是不行的,
dwadewyp
2021-01-16 16:10:42 +08:00
@maocat
dir_path = os.path.abspath(os.curdir) + '/animal'

sys.path.append(dir_path)
亲测 也是无效
maocat
2021-01-16 17:25:19 +08:00
glob 包动态解析拿出路径,for 循环然后解析用内置 exec 方法导入,还有一种方法是 django 有个方法 impo
rt_string 你看下源码很容易改改
@dwadewyp
tmackan
2021-01-16 18:24:58 +08:00
@xchaoinfo 专业
@dwadewyp py 中有个 inspect 的反射包,但是看了下文档,没办法满足你的需求
https://www.cnblogs.com/yaohong/p/8874154.html
dwadewyp
2021-01-16 18:36:14 +08:00
@tmackan inspect 刚才 我也简单看了下 貌似确实不满足
dwadewyp
2021-01-16 18:41:17 +08:00
已解决:
在 animal __init__.py
```
import os
import pkgutil

pkgpath = os.path.dirname(__file__)
pkgname = os.path.basename(pkgpath)

for _, file, _ in pkgutil.iter_modules([pkgpath]):
__import__(pkgname+'.'+file)
```
julyclyde
2021-01-18 14:21:20 +08:00
安装包的时候注册 entrypoint,然后 init 阶段遍历加载

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/745343

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX