我能找到的每一份文档和答案都说,为了检查程序是否被“冻结”(例如,一个exe ),我们可以通过以下方式使用getattr(sys, 'frozen', False)
:
import sys
if getattr(sys, 'frozen', False):
print('program is frozen exe')
else:
print('program is a .py script')
如果False
属性不存在,则默认返回frozen
,而不是抛出AttributeError。控制台中的一个示例:
>>> 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
这一切都很好,但是有一个更短的版本可以完成相同的工作,除非我遗漏了一些东西:
hasattr(sys, 'frozen')
它只返回True
或False
,而不需要指定缺省值。尽管这样做更短,而且可能更易读,但每个文档和在线应答都使用getattr
。我肯定有一个聪明的区别,我可能忽略了,这就是为什么我要问这个问题。
引用getattr
的示例源
hasattr
)发布于 2021-10-01 13:20:05
PyInstaller文档本身使用了代码这里的getattr
样式块,因此通过复制粘贴效应,它将激增。
那么问题就变成了:为什么PyInstaller文档会这样做呢?正如其他人在评论中所说的,理论上sys.frozen
可以设置为False
或其他一些虚妄值,在这种情况下,hasattr(sys, 'frozen')
仍然会返回True
>>> 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
,但其值是假的?让我们检查一下源代码:
$ 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
因此,这个变量只在两个场景中设置:
True
,同时加载/引导;以及'|_|GLYH@CK'
。它从不会从PyInstaller那里得到虚假的值。
因此,在实践中,使用hasattr(sys, 'frozen')
会很好。从正确性的角度来看,这感觉是错误的,因为这是一个处理不当的边缘案例,这可能是PyInstaller文档使用getattr
的原因:更多的是未来证明。
https://stackoverflow.com/questions/59238237
复制相似问题