Python 如何在模块中声明变量的名称? 动机

Python 如何在模块中声明变量的名称? 动机,python,Python,我有以下动机问题-我想在我的项目中使用稍微增强的日志记录。为此,我正在创建模块my_logging,其用法与logging类似。最重要的是,myu日志需要有方法debug,info等 问题: 假设您有一组方法方法1,方法2。。您希望在模块中有一个模块(例如调试,信息,…在我的日志记录中),并且您知道这些方法的实现将相当相似 实现这一点最干净的方法是什么 可能的解决方案 解决方案1 使用参数化方法分别定义每个方法。你能够做到这一点,因为你事先知道所有的方法 def参数化方法(参数): ... 定义

我有以下动机问题-我想在我的项目中使用稍微增强的日志记录。为此,我正在创建模块
my_logging
,其用法与
logging
类似。最重要的是,
myu日志
需要有方法
debug
info

问题: 假设您有一组方法
方法1
方法2
。。您希望在模块
中有一个
模块
(例如
调试
信息
,…在
我的日志记录中
),并且您知道这些方法的实现将相当相似

实现这一点最干净的方法是什么

可能的解决方案 解决方案1 使用参数化方法分别定义每个方法。你能够做到这一点,因为你事先知道所有的方法

def参数化方法(参数):
...
定义方法_1():
_参数化通用方法(方法1参数)
def方法_2():
_参数化通用方法(方法2参数)
...
讨论 显然,这太长,重复的代码太多。如果这些方法太多,那就太乏味了

另一方面,方法是在“编译时”声明的,它可以很好地处理
键入
等等

通过生成代码,可以大大避免繁琐的工作

方法=[
(“方法1”,方法1参数),
(“方法2”,方法2参数),
...
]
方法_模板=“”
def{0}():
_参数化通用方法({1})
'''
将open('module.py','w')作为f:
#这里可能有一些模块头
对于名称,方法中的参数:
印刷品(
方法\模板格式(名称、参数)
文件=f
)
#也许是一些页脚
但这迫使您关心python文件,它不直接属于您的项目。您需要有generator文件,以便在
模块中进行一些更改
并运行该文件。这不属于(在我看来)标准开发周期,因此它不是很好,尽管非常有效

另外,为了完整起见,在下面的代码片段中,您可以使用
方法工厂
来代替
\u参数化的通用方法

def方法工厂(方法参数):
定义参数化通用方法(参数):
...
返回参数化通用方法(方法参数)
方法1=方法工厂(方法1参数)
方法2=方法2工厂(方法2参数)
解决方案2 在我看来,在运行时创建这些方法是一种更简洁的方法

方法=[
(“方法1”,方法1参数),
(“方法2”,方法2参数),
...
]
对于名称,方法中的参数:
globals()[name]=方法工厂(参数)
讨论 我认为这是一种非常优雅的方式,从纯Pythonic的“动态”的观点来看是可以的。 IDE及其帮助以引用解析和“编译时”键入的形式出现了问题

导入模块
模块.方法_1()
如果使用另一个模块中的
模块
,当然找不到这些方法,并且会出现警告(在“编译时”,这不是实际的错误)。魅力四射

Cannot find reference 'method' in 'module.py'
显然,您不想全局压制这些警告,因为它们通常非常有用。此外,此类警告也是使用IDE的原因之一

此外,您可以针对特定行禁用它(如PyCharm中的任何警告),但这会造成代码中的大量污染

或者你可以忽略这些警告,这通常是非常非常坏的习惯

解决方案3——也许? 在Python模块中,您可以通过属性
\uuuuu all\uuuu
指定特定模块导出/提供的名称

在理想世界中,类似这样的事情是可行的

方法=(
(“方法1”,方法1参数),
(“方法2”,方法2参数),
...
)
__all_uz=[名称对应名称,方法中的参数]
对于名称,方法中的参数:
globals()[name]=方法工厂(参数)
讨论 请注意,可以在“编译时”对
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

我的想法是,这将正确地通知其他模块尚未创建的方法的名称,并且在保留函数的良好动态创建时不会出现警告

问题是它并没有按计划工作,因为Python显然无法重新组织这样的all属性,导入模块中的引用警告仍然存在

更具体的问题 有没有办法让
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?还是有类似的时尚


谢谢。

有关IDE级解决方案,请参阅

有人提取了抑制列表,在那里找到了一个:

import module

# noinspection PyUnresolvedReferences
module.a()

module.b()
将仅禁用一行检查


或者,如果您不想自己编写多个类似的函数,您可以让python为您编写:

from os import path


function_template = '''
def {0}():
    print({0})
    
'''

with open(path.abspath(__file__), 'a') as fp:
    for name, arg in zip('abcde', range(5)):
        fp.write(function_template.format(name, arg))
这将使用生成的函数扩展当前脚本


如果您只想以最少的输入工作量包装日志函数,请尝试
close

import logging


def make_function(name: str = None):
    logger = logging.getLogger(name)
    logging.basicConfig(format="%(asctime)s | %(name)s | %(levelname)s - %(message)s")

    def wrapper(log_level):
        level_func = getattr(logger, log_level)

        def alternative_logging(msg, *args):
            nonlocal level_func
            level_func(msg)
            # add some actions here, maybe with args

        return alternative_logging

    return map(wrapper, ('debug', 'info', 'warning', 'error', 'critical'))


debug, info, warning, error, critical = make_function('Nice name')
debug2, info2, warning2, error2, critical2 = make_function('Bad name')


warning('oh no')
warning2('what is it')
error('hold on')
error2('are ya ok')
critical('ded')
critical2('not big surprise')
输出:

2020-09-06 12:06:59742 |好名字|警告-哦不
2020-09-06 12:06:59742 |坏名声|警告-是什么
2020-09-06 12:06:59742 |好名字|错误-稍等
2020-09-06 12:06:59742 |坏名字|错误-你还好吗
2020-09-06 12:06:59742 |好听的名字|关键的
2020-09-06 12:06:59742 |坏名声|关键-没什么大惊喜

并始终将完整的错误消息(从单词“Traceback”开始)作为文本(而不是屏幕截图)进行讨论(而不是评论)。还有其他有用的信息。最好显示导致此问题的代码。可能您导入了不同的同名文件,但它没有此方法。或者你们在函数中定义变量,然后它就是局部变量