`<=` 对 python 集合和布尔值有什么作用?
What does `<=` do with python sets and booleans?
我在标准库的 shutil
模块中发现了一些我不理解的代码。
_use_fd_functions
最终持有一个 truthy/falsy 值,它的初始化如下:
_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()
当然,由于经验丰富的开发人员无法在几秒钟内破译代码,所以代码太聪明了。但它是如何工作的,它有什么作用?
您的答案在 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
是一组函数。
中Pythonand
有lower precedence than <=
so your set comparison is evaluated first. For set
this operator checks if the first set is a subset第二组。
os.supports_dir_fd
列出了您可以执行的文件操作类型。这可能因操作系统而异,因此 os
模块根据当前环境采用不同的代码路径。对于每个函数,_add
将检查它是否在当前 OS 上被允许。因此,您询问的代码片段的目的是查看是否支持操作 open
、stat
、unlink
和 rmdir
,然后它会进行更多检查对于 shutil
想要使用的特定行为。最后,_use_fd_functions
会告诉 shutil
是否应该使用文件描述符函数 ("fd"),这取决于您在当前环境中可以做什么。
我在标准库的 shutil
模块中发现了一些我不理解的代码。
_use_fd_functions
最终持有一个 truthy/falsy 值,它的初始化如下:
_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()
当然,由于经验丰富的开发人员无法在几秒钟内破译代码,所以代码太聪明了。但它是如何工作的,它有什么作用?
您的答案在 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
是一组函数。
中Pythonand
有lower precedence than <=
so your set comparison is evaluated first. For set
this operator checks if the first set is a subset第二组。
os.supports_dir_fd
列出了您可以执行的文件操作类型。这可能因操作系统而异,因此 os
模块根据当前环境采用不同的代码路径。对于每个函数,_add
将检查它是否在当前 OS 上被允许。因此,您询问的代码片段的目的是查看是否支持操作 open
、stat
、unlink
和 rmdir
,然后它会进行更多检查对于 shutil
想要使用的特定行为。最后,_use_fd_functions
会告诉 shutil
是否应该使用文件描述符函数 ("fd"),这取决于您在当前环境中可以做什么。