Python中的逻辑错误'if'评估
我刚刚发生了最奇怪的错误。 我没有机会完全debugging它,但我想发布这个,看看是否有其他人有类似的问题。
问题
下面的代码是在一个函数下载一个文件。 if
最终文件存在, if
语句逻辑将跳过下载步骤。
log.debug('force: {}, isfile: {}'.format(force, os.path.isfile(fasta_path))) log.debug('if result: {}'.format(force or not os.path.isfile(fasta_path))) if force or not os.path.isfile(fasta_path): # we don't have the file, so download it log.info('Downloading reference FASTA') else: log.info('FASTA found--skipping download.')
运行时,打印出下列内容:
[17-02-14 05:03:32 - __main__:119 - DEBUG] force: False, isfile: True [17-02-14 05:03:32 - __main__:120 - DEBUG] if result: False [17-02-14 05:03:32 - __main__:124 - INFO] Downloading reference FASTA
分解
force
variables旨在允许用户“强制”下载,而不pipe现有数据如何。 正如你在输出中看到的那样,它是False
。
文件path有效,文件存在,如输出中所示。
因此,if语句本质上是False or not True
,应该(也是在输出中)评估为False
; 然而, True
条件( Downloading reference
)被执行。
我曾尝试括号和一些最小的debugging,但我找不到任何理由发生。 例如,以下在python解释器中按预期工作:
if False or not True: print('hi') else: print('bye')
环境
在Docker容器中,ubuntu 16.04上的Python 3.5会发生此问题。
正如@ user2357112在注释中指出的那样,force很可能是一个string:
>>> print('if result: {}'.format("False" or not True)) if result: False >>> "False" or not True 'False' >>> type("False" or not True) <class 'str'> >>> bool("False" or not True) True
这可能是为什么第二个debugging语句显示False(因为它显示的是string而不是布尔值)。 你可以testing这个
log.debug('if result: {}'.format(bool(force or not os.path.isfile(fasta_path))))
( if result: True
预期输出)或
log.debug('if result: {}'.format(repr(force or not os.path.isfile(fasta_path))))
( if result: 'False'
期望的输出if result: 'False'
– 注意引号是一个string而不是布尔值)
编辑说明:按照4.2。 布尔操作expression式x or y
根据if x is false, then y, else x
。 从4.1开始。 真值testing只有空序列是False
(在真值testing中)序列'False'
是True
。 因此'False' or x
评估string'False'
(独立于x
的值)。 打印期间, 'False'
不被解释为布尔值。 然而,在if语句中,string'False'
被testing为Truth
…
FWIW,在Windows机器上运行的代码稍作修改,Python 2.6.5:
def stackOverflow(self, force, fasta_path): logging.info('force: {0}, isfile: {1}'.format(force, os.path.isfile(fasta_path))) logging.info('if result: {0}'.format(force or not os.path.isfile(fasta_path))) if force or not os.path.isfile(fasta_path): # we don't have the file, so download it logging.info('Downloading reference FASTA') else: logging.info('FASTA found--skipping download.')
这需要force
的预期path(“跳过下载”)为False
,path存在。 电话是:
stackOverflow(False, r'C:\temp\pythoncode.txt')
正如注释所暗示的,将第一个参数作为一个string将采用神秘的path(“下载”)。
stackOverflow("False", r'C:\temp\pythoncode.txt')
- 有没有一种方法可以在Dockers上使用Windows的GUIfunction
- 如何在dockerized Rails应用程序中创buildMysqltesting数据库?
- 我如何使用REST API与Docker引擎进行交互?
- System.IO.FileNotFoundException:无法加载文件或程序集“System.Net.Security,Version = 4.0.0.0
- 一个Linux应用程序可以使用Docker在Windows上运行吗?
- 鱼壳通过命令传递参数
- 重新启动后,如何将IP保留在单个节点上的dockerized Consul群集中
- Windows上的Docker运行缓慢,为什么?
- Docker:如何从一个正在运行的容器向另一个容器发送信号?