什么`< =`做python集和布尔值?

时间:2017-02-15 09:56:22

标签: python shutil

我在标准库的shutil模块中找到了一些我不理解的代码。

_use_fd_functions最终会保留一个真值/假值,并按照以下方式进行初始化:

_use_fd_functions = ({os.open, os.stat, os.unlink, os.rmdir} <=
                     os.supports_dir_fd and
                     os.listdir in os.supports_fd and
                     os.stat in os.supports_follow_symlinks)

{os.open, os.stat, os.unlink, os.rmdir}都是函数,<=的正确参数看起来像布尔值,但根据来源,它们是函数和函数集。

我无法在Python 3.5.2 repl中重新创建此行为:(已删除回溯)

>>> {lambda x: x} <= True
TypeError: unorderable types: set() <= bool()
>>> {True} <= True
TypeError: unorderable types: set() <= bool()
>>> {lambda x: x} <= (lambda x: x+1)
TypeError: unorderable types: set() <= function()
>>> {lambda x: x} <= (lambda x: x+1) in {lambda x: x+1}
TypeError: unorderable types: set() <= function()

当然,由于经验丰富的开发人员无法在几秒钟内解密代码,因此代码太聪明了。但它是如何工作的,它做了什么?

1 个答案:

答案 0 :(得分:6)

您的答案可在os module

中找到
_set = set()
_add("HAVE_FACCESSAT",  "access")
_add("HAVE_FCHMODAT",   "chmod")
_add("HAVE_FCHOWNAT",   "chown")
_add("HAVE_FSTATAT",    "stat")
_add("HAVE_FUTIMESAT",  "utime")
_add("HAVE_LINKAT",     "link")
_add("HAVE_MKDIRAT",    "mkdir")
_add("HAVE_MKFIFOAT",   "mkfifo")
_add("HAVE_MKNODAT",    "mknod")
_add("HAVE_OPENAT",     "open")
_add("HAVE_READLINKAT", "readlink")
_add("HAVE_RENAMEAT",   "rename")
_add("HAVE_SYMLINKAT",  "symlink")
_add("HAVE_UNLINKAT",   "unlink")
_add("HAVE_UNLINKAT",   "rmdir")
_add("HAVE_UTIMENSAT",  "utime")
supports_dir_fd = _set

os.supports_dir_fd是一组函数。

在Python andlower precedence<=更早,因此首先评估您的集合比较。对于set,此运算符检查第二组的第一组is a subset

os.supports_dir_fd列出了您可以执行的文件操作类型。这可能因操作系统而异,因此os模块根据当前环境采用不同的代码路径。对于每个函数,_add将检查当前操作系统是否允许它。因此,您要问的代码段的目的是查看是否支持操作openstatunlinkrmdir,然后再进行一些检查对于shutil想要使用的特定行为。最后,_use_fd_functions将告诉shutil是否应该使用文件描述符函数(&#34; fd&#34;),具体取决于您在当前环境中可以执行的操作。