首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么sys.frozen使用getattr而不是hasattr呢?

为什么sys.frozen使用getattr而不是hasattr呢?
EN

Stack Overflow用户
提问于 2019-12-08 17:54:24
回答 1查看 3.5K关注 0票数 2

我能找到的每一份文档和答案都说,为了检查程序是否被“冻结”(例如,一个exe ),我们可以通过以下方式使用getattr(sys, 'frozen', False)

代码语言:javascript
运行
复制
import sys
if getattr(sys, 'frozen', False):
    print('program is frozen exe')
else:
    print('program is a .py script')

如果False属性不存在,则默认返回frozen,而不是抛出AttributeError。控制台中的一个示例:

代码语言:javascript
运行
复制
>>> getattr(sys, 'frozen')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'sys' has no attribute 'frozen'
>>> getattr(sys, 'frozen', False)
False
>>> hasattr(sys, 'frozen')
False

这一切都很好,但是有一个更短的版本可以完成相同的工作,除非我遗漏了一些东西:

代码语言:javascript
运行
复制
hasattr(sys, 'frozen')

它只返回TrueFalse,而不需要指定缺省值。尽管这样做更短,而且可能更易读,但每个文档和在线应答都使用getattr。我肯定有一个聪明的区别,我可能忽略了,这就是为什么我要问这个问题。

引用getattr的示例源

EN

回答 1

Stack Overflow用户

发布于 2021-10-01 13:20:05

PyInstaller文档本身使用了代码这里getattr样式块,因此通过复制粘贴效应,它将激增。

那么问题就变成了:为什么PyInstaller文档会这样做呢?正如其他人在评论中所说的,理论上sys.frozen可以设置为False或其他一些虚妄值,在这种情况下,hasattr(sys, 'frozen')仍然会返回True

代码语言:javascript
运行
复制
>>> class Stuff:
...     pass
... 
>>> x = Stuff()
>>> x.yes = True
>>> hasattr(x, 'yes')
True
>>> getattr(x, 'yes', False)
True
>>> x.no = False
>>> hasattr(x, 'no')
True
>>> getattr(x, 'no', False)
False

但是,正如PyInstaller所使用的那样,是否可以设置sys.frozen,但其值是假的?让我们检查一下源代码:

代码语言:javascript
运行
复制
$ git clone git://github.com/pyinstaller/pyinstaller
Cloning into 'pyinstaller'...
...
$ cd pyinstaller
$ git grep '\(sys\.frozen\|frozen = \)' PyInstaller
PyInstaller/loader/pyiboot01_bootstrap.py:    sys.frozen = True
PyInstaller/utils/win32/winutils.py:            # True if "sys.frozen" is currently set.
PyInstaller/utils/win32/winutils.py:            is_sys_frozen = hasattr(sys, 'frozen')
PyInstaller/utils/win32/winutils.py:            # Current value of "sys.frozen" if any.
PyInstaller/utils/win32/winutils.py:            sys_frozen = getattr(sys, 'frozen', None)
PyInstaller/utils/win32/winutils.py:            sys.frozen = '|_|GLYH@CK'
PyInstaller/utils/win32/winutils.py:            # If "sys.frozen" was previously set, restore its prior value.
PyInstaller/utils/win32/winutils.py:                sys.frozen = sys_frozen
PyInstaller/utils/win32/winutils.py:                del sys.frozen

因此,这个变量只在两个场景中设置:

  1. True,同时加载/引导;以及
  2. 在实用程序方法中临时执行'|_|GLYH@CK'

它从不会从PyInstaller那里得到虚假的值。

因此,在实践中,使用hasattr(sys, 'frozen')会很好。从正确性的角度来看,这感觉是错误的,因为这是一个处理不当的边缘案例,这可能是PyInstaller文档使用getattr的原因:更多的是未来证明

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59238237

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档