如何使模块导入已导入模块的模块

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使模块导入已导入模块的模块相关的知识,希望对你有一定的参考价值。

我经常发现自己想在运行代码时通过打印某些功能来测试某些功能。我喜欢使用f字符串使输出更具描述性。像这样的东西:

foo = 2
bar = 5
print(f'foo * bar = foo * bar')

输出foo * bar = 10。很好,但是制作一个可以随时导入并自动为我完成的模块真的很方便。像这样的东西:

eval_print.py

def eval_print(function_as_str):
    print(f'function_as_str = eval(function_as_str)')

if __name__ == '__main__':
    eval_print('2 + 2')

这很有效,直到我实际导入为止。我在这里遇到了问题:

celsius.py:

from eval_print import eval_print

class Celsius:
    def __init__(self, temperature = 0):
        self.temperature = temperature

    def to_fahrenheit(self):
        return (self.temperature * 1.8) + 32

man = Celsius()

man.temperature = 37


eval_print('man.temperature')
eval_print('man.to_fahrenheit()')

运行celsius.py给我一个NameError异常,因为eval_print无权访问celsius.py

有什么方法可以导入导入模块的模块?在这种情况下,我想自动导入celsius.py或任何其他模块可以将其导入到eval_print.py

答案

这是为功能执行此操作的方法。这仅用于位置参数,但您可以将其用于命名参数。

def printe(fun, args):
    sargs = ', '.join([str(arg) for arg in args])
    print(f'fun.__name__(sargs) = fun(*args)')

当给定实际函数和参数为元组时,将其打印出来。

>>> printe(foo, (1,))
foo(1) = 2

问题是,如果您将一个函数分配给另一个变量,它将不起作用。

>>> bar = foo
>>> printe(bar, (1,))
foo(1) = 2

不确定如何执行变量,但我会继续考虑。

另一答案

您可以这样编写一个函数调用日志装饰器((也受到蓝牙答案的启发),然后装饰要检查调用的函数。

def log_call(func):
    def print_call(*args, **kwargs):
        result = func(*args, **kwargs)
        args_str = ", ".join(str(arg) for arg in args)
        kwargs_str = " " + ", ".join(
            f"key=value".format(key, value) for key, value in kwargs.items()
        )
        print(f"func.__name__(args_str,kwargs_str) = result")
        return result

    return print_call


@log_call
def add(x, y, offset=0, from_origin=0):
    return x + y + offset + from_origin


print(add(1, 2, offset=10, from_origin=5))

输出:

add(1, 2, offset=10, from_origin=5) = 18
18

以上是关于如何使模块导入已导入模块的模块的主要内容,如果未能解决你的问题,请参考以下文章

Python3/cloud9/lambda - 使导入的模块可用于 lambda

如何查找 pip3 已安装模块的导入名称/密钥

无法导入已安装的模块

重新加载已导入另一个模块的模块

如何导入 luarocks 本地模块

如何在 Android Studio 4.2 上导入 .AAR 模块