我有以下奇怪的设置.考虑不同目录中的3个脚本:

  • root1/folderA/scriptA.py
  • root2/folderB/scriptB.py公司
  • root2/folderC/scriptC.py公司

第一个文件及其位置完全可以修改.第二个和第三个是完全固定的.

脚本A.py包含父类:

class A:
    def get_path(self):
        # ...
        # code to determine "my_path"
        # ...
        return my_path

脚本B.py包含一个子类:

from root1.folderA.scriptA import A

class B(A):
    pass

脚本C.py包含要执行的代码:

from root2.folderB.scriptB import B

if __name__ == "__main__":
    b = B()
    print(b.get_path()) # want print root/folderB/scriptB.py

在scriptC中.py我想要的是获取子类声明文件路径的行为(无需任何硬编码).有没有办法让A.get_path()人有这样的行为?

我试着研究了inspectos.pathpathlib个模块,但没有任何运气.

推荐答案

看起来诀窍是使用__init_subclass__,它在类被子类化时运行,与类的__module__属性一起检索其包含的模块,使用__file__检索python脚本或模块的绝对路径.

例如,在script_a.py中:

import sys
from pathlib import Path


class PathInfo:
    __slots__ = ()

    path: Path

    def __init_subclass__(cls, **kwargs):
        mod = sys.modules[cls.__module__]
        # `__file__` is a string, so we want to convert to a `Path` so it's easier to work with
        cls.path = Path(mod.__file__)


class A(PathInfo):
    __slots__ = ()

script_b.py:

from script_a import A


class B(A):
    pass


# prints: /Users/<name>/PycharmProjects/my-project/script_a.py
print(A().path)
# prints: /Users/<name>/PycharmProjects/my-project/script_b.py
print(B.path)

Python相关问答推荐

为什么我的Python代码在if-else声明中的行之前执行if-else声明中的行?

处理(潜在)不断增长的任务队列的并行/并行方法

使用@ guardlasses. guardlass和注释的Python继承

修复mypy错误-赋值中的类型不兼容(表达式具有类型xxx,变量具有类型yyy)

无法使用requests或Selenium抓取一个href链接

使用setuptools pyproject.toml和自定义目录树构建PyPi包

为什么抓取的HTML与浏览器判断的元素不同?

关于Python异步编程的问题和使用await/await def关键字

当递归函数的返回值未绑定到变量时,非局部变量不更新:

Python Pandas获取层次路径直到顶层管理

Pandas Data Wrangling/Dataframe Assignment

lityter不让我输入左边的方括号,'

在输入行运行时停止代码

python—telegraph—bot send_voice发送空文件

为什么在FastAPI中创建与数据库的连接时需要使用生成器?

Python pint将1/华氏度转换为1/摄氏度°°

以异步方式填充Pandas 数据帧

从一个df列提取单词,分配给另一个列

使用Python TCP套接字发送整数并使用C#接收—接收正确数据时出错

jsonschema日期格式