登录框架

2024-01-09

想象一下有一个框架提供了一个名为logutils.set_up()它根据某些配置设置日志记录。

应尽早设置日志记录,因为导入库期间发出的警告不应丢失。

由于旧方法(if __name__=='__main__':)看起来很难看,我们使用控制台脚本入口点来注册main() method.

# foo/daily_report.py
from framework import logutils
logutils.set_up()
def main():
    ...

我的问题是logutils.set_up()可能会被调用两次:

想象一下有第二个控制台脚本调用logutils.set_up() and imports daily_report.py.

我可以更改框架代码set_up()在第二次调用中不执行任何操作logutils.set_up(),但这感觉很笨拙。我想避免它。

我怎样才能确定logutils.set_up()只执行一次?


有几种方法可以实现该目标,每种方法都有其优点和缺点。

(其中一些与其他答案重叠。我无意抄袭,只是为了提供全面的答案)。


方法一:函数应该做到这一点

保证函数只执行一次的一种方法是使函数本身有状态,使其“记住”它已经被调用过。这或多或少是@eestrada 和@qarma 所描述的。

至于实现这一点,我同意 @qarma 的观点,即使用记忆化是最简单、最理想的方法。互联网上有一些简单的 python 记忆装饰器。标准库中包含的一个是functools.lru_cache。您可以简单地使用它,例如:

@functools.lru_cache
def set_up():  # this is your original set_up() function, now decorated
    <...same as before...>

这里的缺点是它可以说不是set_up维持国家的责任,只是一种职能。有人可以争论这一点should如果被调用两次,则执行两次,并且调用者有责任仅在需要时调用它(如果您确实想运行它两次怎么办)?一般的论点是,函数(为了有用和可重用)不应该对其调用的上下文做出假设。

这个论点在你的情况下有效吗?由您决定。

这里的另一个缺点是,这可以被视为滥用记忆工具。 Memoization是与函数式编程密切相关的工具,应该应用于纯函数。记住一个函数意味着“不需要再次运行它,因为我们已经知道了result”,而不是“不需要再次运行它,因为有一些副作用我们想避免”。

方法二:你认为丑的那个(if __name__=='__main__')

您在问题中已经提到的最常见的Python方式是使用臭名昭著的if __name__=='__main__' https://stackoverflow.com/q/419163/2096752构造。

这保证了该函数仅被调用一次,因为它仅从名为的模块中调用__main__,并且解释器保证您的进程中只有一个这样的模块。

这有效。没有任何并发​​症或警告。这是在 python 中运行主代码(包括设置代码)的方式。已经被考虑了pythonic只是因为它在 python 中非常常见(因为没有更好的方法)。

唯一的缺点是它可以说是丑陋的(从美观角度来看,而不是从代码质量角度来看)。我承认,在我最初几次看到或写下它时,我也皱起了眉头,但你会越来越喜欢它。

方法 3:利用 python 的模块导入机制

Python 已经有一个缓存机制来防止模块被双重导入。您可以通过在新模块中运行设置代码然后导入它来利用此机制。这与@rll 的答案类似。这很简单,要做到:

# logging_setup.py
from framework import logutils
logutils.set_up()

现在,每个调用者都可以通过导入新模块来运行它:

# foo/daily_report.py
import logging_setup # side effect!
def main():
    ...

由于模块仅导入一次,set_up只被调用一次。

这里的缺点是它违反了“显式优于隐式”的原则。 IE。如果你想调用一个函数,就调用它。运行对模块导入时间有副作用的代码并不是一个好习惯。

方法 4:猴子修补

这是迄今为止该答案中最糟糕的方法。不要使用它。但这仍然是完成工作的一种方法。

这个想法是,如果您不希望该函数在第一次调用后被调用,请在第一次调用后对其进行猴子修补(阅读:破坏它)。

from framework import logutils
logutils.set_up_only_once()

Where set_up_only_once可以这样实现:

def set_up_only_once():
    # run the actual setup (or nothing if already vandalized):
    set_up()
    # vandalize it so it never walks again:
    import sys
    sys.modules['logutils'].set_up = lambda: None

缺点:你的同事会讨厌你。


tl;dr:

最简单的方法是使用记忆functools.lru_cache,但它可能不是代码质量方面的最佳解决方案。该解决方案是否足够适合您的情况取决于您。

最安全、最Pythonic的方法,虽然不赏心悦目,但使用if __name__=='__main__': ....

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

登录框架 的相关文章

  • 使用 OpenCV 和/或 Numpy 对两个图像进行 Alpha 混合 [重复]

    这个问题在这里已经有答案了 我想将一个填充纯色的半透明矩形添加到已加载的半透明 PNG 中 这是我正在使用的输入图像示例 该图像加载了标准cv2 IMREAD UNCHANGED标志 以便完美保留 alpha 通道 该输入图像存储在imag
  • ca 证书 Mac OS X

    我需要在emacs 上安装offlineimap 和mu4e 问题是配置 当我运行 Offlineimap 时 我得到 OfflineIMAP 6 5 5 Licensed under the GNU GPL v2 v2 or any la
  • 正则表达式,选择最接近的匹配

    假设以下单词序列 BLA text text text text text text BLA text text text text LOOK text text text BLA text text BLA 我想做的是将 BLA 中的文本
  • 使用数据库进行日志记录

    大多数日志似乎都是纯文本形式 而不是放入 MySQL 其他类型的数据库中 这是否有原因 在我看来 将它们放入数据库将使分析变得非常非常容易 但这会以牺牲速度还是其他什么为代价 我不太关心可移植性 显然你会有数据库连接的文本日志 我能想到两大
  • numpy:大量线段/点的快速规则间隔平均值

    我沿着一维线有许多 约 100 万个 不规则间隔的点 P 这些标记线段 这样 如果点是 0 x a x b x c x d 则线段从 0 gt x a x a gt x b x b gt x c x c gt x d 等 我还有每个段的 y
  • 如何使用 i18n 切换器将“LANGUAGE_CODE”保存到数据库,以便在 Django 中的不同浏览器中语言不会更改?

    有什么办法可以改变它的值LANGUAGE CODE单击按钮 发送请求 时 settings py 中的变量会动态变化吗 我希望用户设置自己的 默认语言 他们的帐户 现在 用户可以使用下拉列表选择他们的首选语言 并且网站会得到完美的翻译 并且
  • 对于相同的查询,MySQL Workbench 比 Python 快得多

    MySQL Workbench 中的以下查询需要 0 156 秒才能完成 SELECT date time minute price id FROM minute prices WHERE contract id 673 AND TIMES
  • Tensorflow 不分配完整的 GPU 内存

    Tensorflow 默认分配所有 GPU 内存 但我的新设置实际上只有 9588 MiB 11264 MiB 我预计大约 11 000MiB 就像我的旧设置一样 张量流信息在这里 from tensorflow python client
  • 如何使用 PyMongo 在重复键错误后继续插入

    如果我需要在 MongoDB 中插入尚不存在的文档 db stock update one document set document upsert True 将完成这项工作 如果我错了 请随时纠正我 但是 如果我有一个文档列表并想将它们全
  • 返回上个月的日期时间对象

    如果 timedelta 在它的构造函数中有一个月份参数就好了 那么最简单的方法是什么 EDIT 正如下面指出的那样 我并没有认真考虑这一点 我真正想要的是上个月的任何一天 因为最终我只会获取年份和月份 因此 给定一个日期时间对象 返回的最
  • Python 3在for循环中更改字典键的值不起作用

    我的 python 3 代码没有按预期工作 def addFunc x y print x y def subABC x y z print x y z def doublePower base exp print 2 base exp d
  • 如何使用 Celery 多工作人员启用自动缩放?

    命令celery worker A proj autoscale 10 1 loglevel info启动具有自动缩放功能的工作人员 当创建多个工人时 me mypc projects x celery multi start mywork
  • 为什么 __instancecheck__ 没有被调用?

    我有以下 python3 代码 class BaseTypeClass type def new cls name bases namespace kwd result type new cls name bases namespace p
  • Jupyter Notebook 中的深色模式绘图 - Python

    我正在使用 Jupyter Notebook 目前正在使用 JupyterThemes 的深色日光主题 我注意到我的绘图不是处于黑暗模式 并且文本仍然是黑色并且在日光照射的背景上无法读取 JupyterThemes 的自述文件建议在 ipy
  • 如何分析组合的 python 和 c 代码

    我有一个由多个 python 脚本组成的应用程序 其中一些脚本正在调用 C 代码 该应用程序现在的运行速度比以前慢得多 因此我想对其进行分析以查看问题所在 是否有工具 软件包或只是一种分析此类应用程序的方法 有一个工具可以将 python
  • 为 Logstash 中的新字段设置 Elasticsearch Analyzer

    通过使用GROK filter 我们可以向Logstash添加新字段 但是 我想知道如何为该特定字段设置分析器 例如 我有一个新的 id 字段 其中有一个字段 例如a b 但是 Elasticsearch 附带的普通分析器会将其分解为a a
  • Python:无法使用 os.system() 打开文件

    我正在编写一个使用该应用程序的 Python 脚本pdftk http www pdflabs com tools pdftk the pdf toolkit 几次来执行某些操作 例如 我可以在 Windows 命令行 shell 中使用
  • 沿轴 0 重复 scipy csr 稀疏矩阵

    我想重复 scipy csr 稀疏矩阵的行 但是当我尝试调用 numpy 的重复方法时 它只是将稀疏矩阵视为对象 并且只会将其作为 ndarray 中的对象重复 我浏览了文档 但找不到任何实用程序来重复 scipy csr 稀疏矩阵的行 我
  • 如何使用 Python 3 正确显示倒计时日期

    我正在尝试获取将显示的倒计时 基本上就像一个世界末日时钟哈哈 有人可以帮忙吗 import os import sys import time import datetime def timer endTime datetime datet
  • Python 中的字符串slugification

    我正在寻找 slugify 字符串的最佳方法 蛞蝓 是什么 https stackoverflow com questions 427102 in django what is a slug 我当前的解决方案基于这个食谱 http code

随机推荐

  • 如何从文档中删除所有肖像图片

    我正在对文档图像进行 OCR 处理 我想检测所有图片并从文档图像中删除 我想保留文档图像中的表格 一旦我检测到图片 我就会将其删除 然后进行 OCR 我试图找到轮廓试图检测所有更大的区域 不幸的是它也检测到表格 还如何删除在文档图像中保留其
  • 通过 Python 代码使用 SignalR 服务器

    将 Python 与 SignalR 集成有哪些选项 Python 代码是大型第三方产品的一部分 与语言偏好无关 SignalR 服务器提供对现有 NET 产品的订阅 我们希望通过 Python 重用 NET SignalR 服务器 pyt
  • Java中如何随机选择图片?

    我正在制作一个将使用以下代码的程序 JLabel MyImage new JLabel new ImageIcon image1 png 但是 我想让随机图片出现 比如 image2 image3 image4 我该如何做到这一点 不使用L
  • @RequestMapping 在 Spring Boot 内部如何工作?

    RestController RequestMapping employee public class Employee RequestMapping save public void saveEmployee saving employe
  • blockIdx 与区块执行顺序相关吗?

    之间有什么关系吗blockIdx以及线程块在 GPU 设备上执行的顺序 我的动机是 我有一个内核 其中多个块将从全局内存中的同一位置读取 如果这些块能够同时运行 那就太好了 因为 L2 缓存命中很好 在决定如何将这些块组织成网格时 可以肯定
  • 如何识别无法嵌入文件的 YouTube 视频

    我有一个移动应用程序 可以在网络视图中嵌入一些 YouTube 视频 问题是 使用 YouTube Data API v3 我得到了 可嵌入 要显示的项目 但其中一些说 视频不可用 当我将相同的代码粘贴到 jsfiddle 或域或某种网络服
  • docker jboss7 战争提交。服务器启动失败且无法恢复

    有没有办法将 war 文件部署到在 docker 容器内运行的 Jboss as7 中 因为我的 jboss 服务器在 docker 提交后似乎失败了 Could not rename usr local share jboss stand
  • Keycloak + Kerberos 身份验证:机制级别:无效参数 (400) - 无法找到适当类型的密钥来解密 AP REP - 使用 HMAC 的 RC4

    我有以下内容 JBoss EAP 7 2 2 上的 Spring Web 应用程序 Machine CentOs CentO 上的 Keycloak 3 3 4 活动目录 我们在 OpenJDK 8 上运行 用户使用其 Active Dir
  • CG 3.0会泄露吗?

    我发现 CG 似乎存在内存泄漏 我通过 nvidia com 提交了一份报告 但如果您尝试这样做here http will sherif appspot com html d3d11 DirectWrite html 如果你删除那行 cg
  • 语法错误:编译 ejs 时参数列表后缺少 )

    编译 ejs 时 我收到错误 参数列表后缺少 我尝试了很多次 但找不到问题所在 这是导致错误的 ejs 这段代码有什么问题 h2 class page title Products h2 br a href admin products a
  • WPF Ribbon - 隐藏快速访问工具栏

    如何在 WPF 功能区中隐藏快速访问工具栏 For 您可以使用隐藏它VisualTreeHelper 上Loaded事件处理程序 只需将包含快速访问工具栏的行大小调整为 0 private void RibbonLoaded object
  • 安卓L | libusb_init 返回 LIBUSB_ERROR_OTHER (-99)

    我尝试使用libusb在未 root 的 Nexus 5 上 如建议的那样这种方法 https stackoverflow com a 24243605 902217 通过将 USB 文件描述符从 java 传输到本机端 我的应用程序通过以
  • 将空图添加到ggplot2中的facet_wrap

    我正在尝试创建 3 个图 其中所有面板应具有相同的大小 所以我认为解决方案可能是facet wrap 我的问题是 我不希望每个图表中有相同数量的图表 df lt data frame group c 1 1 2 2 2 3 3 name c
  • 在树枝模板中设置多维数组中单个对象的值

    对于项目需要 我需要在渲染之前更改一些表单字段数据 为此 我迭代表单元素并动态更改我需要的值 问题是我无法改变价值 我收到这个错误 Unexpected token punctuation of value end of statement
  • Emacs 搜索和替换的好教程 + 参考吗? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 对于 Emacs 的新用户来说 有什么好的教程 参考来学习和熟悉 Emacs 的搜索 替换和正则表达式功能吗 In Emacs press
  • 动态生成的 Perl Moose 访问器

    请参阅以下基于 Moose 的 Perl 代码片段 BusinessClass gt meta gt add attribute Key gt is gt rorw isa gt MooseType lazy gt 0 required g
  • C语言中如何连接两个整数

    Stack Overflow 用许多其他语言回答了这个问题 但没有用 C 语言回答 所以我想我会问 因为我有同样的问题 C语言中如何连接两个整数 Example x 11 y 11 我想要 z 如下 z 1111 其他示例尝试使用字符串来执
  • N层架构中如何维护事务

    我正在 N 层架构中开发应用程序 众所周知 我们需要在插入 更新 删除操作时实现事务 请告诉我如何在 N 层架构的 c net 中使用事务 我的架构是这样的 Applicationform gt middle Layre gt Factor
  • simple_form 带有自定义包装器的自定义输入

    我正在尝试在我的应用程序中为货币进行自定义输入 我有那些 bootstrap 包装器等 我认为它带有 simple form 或 bootstrap gem 所以 我可以做类似的事情 它的工作原理正如预期的那样 问题是 我在很多地方都需要同
  • 登录框架

    想象一下有一个框架提供了一个名为logutils set up 它根据某些配置设置日志记录 应尽早设置日志记录 因为导入库期间发出的警告不应丢失 由于旧方法 if name main 看起来很难看 我们使用控制台脚本入口点来注册main m