2017-02-15 11 views
1

Я нашел код в модуле shutil в стандартной библиотеке, которую я не понимаю.Что делает `<=` делать с наборами python и booleans?

_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 РЕПЛ: (tracebacks удален)

>>> {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() 

Конечно, так как опытный разработчик не смог расшифровать код в течение нескольких секунд, код слишком умный. Но как это работает, и что он делает?

+0

Является ли исходный код Python 2? Там, сравнение 'set' с' boolean' не бросает 'TypeError'. Я не помню правила (что является частью причины такого поведения, которое было удалено), но здесь происходит что-то умное. –

+0

Я действительно не понимаю, что это делает, но '{lambda x: x} <= (lambda x: x + 1) в {lambda x: x + 1}' возвращает 'False' в Python 2.7 бит. – roganjosh

+0

@ juanpa.arrivillaga Путь к 'shutil', который я прочитал, это' C: \ Python35 \ Lib \ shutil.py'. Я ожидаю, что это Python 3.5. –

ответ

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 and есть lower precedence, чем <=, поэтому сначала оценивается ваше сравнение. Для set этот оператор проверяет, установлен ли первый набор is a subset второго набора.

os.supports_dir_fd перечисляет вид операций с файлами, которые вы можете выполнить. Это может различаться между операционными системами, поэтому модуль os использует разные коды кода в зависимости от текущей среды. Для каждой функции _add проверяет, разрешено ли это для текущей ОС. Таким образом, целью фрагмента кода, о котором вы спрашиваете, является проверка того, поддерживаются ли операции open, stat, unlink и rmdir, а затем он выполняет несколько проверок определенных типов поведения, которые хочет использовать shutil. В конце концов, _use_fd_functions скажет, должен ли shutil использовать функции дескриптора файла («fd») вообще, в зависимости от того, что вы можете сделать в текущей среде.

+1

Возможно, я медленный, но я изо всех сил пытаюсь объединить цель исходного кода. Можете ли вы заявить об этом на высоком уровне? – roganjosh

+0

Я тоже пытался это объяснить. –

+0

Оцените, мне сейчас гораздо больше смысла – roganjosh