У вас есть #include <unistd.h>
, где объявлено fork()
.
Итак, вам, вероятно, нужно сообщить системе, чтобы показать определения POSIX, прежде чем включать заголовки системы:
#define _XOPEN_SOURCE 600
Вы можете использовать 700, если считаете, что ваша система в основном совместима с POSIX 2008 или даже 500 для более старой системы. Поскольку fork()
существует бесконечно, он будет отображаться с любым из них.
Если вы компилируете с -std=c99 --pedantic
, то все объявления для POSIX будут скрыты, если вы явно не запросите их как показано .
Вы также можете играть с _POSIX_C_SOURCE
, но с помощью _XOPEN_SOURCE
подразумеваются правильные соответствующие _POSIX_C_SOURCE
(и _POSIX_SOURCE
и т. д.).
Я считаю, что на этот вопрос уже ответили другие пользователи до меня, поэтому я добавляю его только для полноты: оператор with
упрощает обработку исключений, инкапсулируя общую подготовку и задачи очистки в так называемых менеджерах контекста . Более подробную информацию можно найти в PEP 343 . Например, оператор open
сам по себе является диспетчером контекста, который позволяет вам открывать файл и держать его открытым, пока выполняется в контексте оператора with
, в котором вы использовал его, и закройте его, как только вы покинете контекст, независимо от того, покинули ли вы его из-за исключения или во время обычного потока управления. Таким образом, оператор with
может использоваться способами, аналогичными шаблону RAII в C ++: некоторый ресурс приобретается оператором with
и освобождается, когда вы покидаете с контекстом
.
Некоторые примеры: открытие файлов с использованием с open (filename) как fp:
, получение блокировок с использованием с блокировкой:
(где lock
является экземпляром threading.Lock
). Вы также можете создавать свои собственные контекстные менеджеры, используя декоратор contextmanager
из contextlib
.Например, я часто использую это, когда мне нужно временно изменить текущий каталог, а затем вернуться туда, где я был:
from contextlib import contextmanager
импорт ОС
@contextmanager
def working_directory (путь):
current_dir = os.getcwd ()
os.chdir (путь)
пытаться:
урожай
наконец:
os.chdir (current_dir)
с рабочим_каталогом ("данные / материал"):
# сделать что-нибудь с данными / вещами
# вот я снова вернулся в исходный рабочий каталог
Вот еще один пример, который временно перенаправляет sys.stdin
, sys.stdout
и sys.stderr
на другой дескриптор файла и восстанавливает их позже:
] из contextlib import contextmanager
import sys
@contextmanager
def перенаправлен (** kwds):
stream_names = ["стандартный ввод", "стандартный вывод", "стандартный поток"]
old_streams = {}
пытаться:
для sname в stream_names:
stream = kwds.get (sname, Нет)
если stream не равен None и stream! = getattr (sys, sname):
old_streams [sname] = getattr (sys, sname)
setattr (sys, sname, stream)
урожай
наконец:
для sname поток в old_streams.iteritems ():
setattr (sys, sname, stream)
с перенаправлением (stdout = open ("/ tmp / log.txt", "w")):
# эти операторы печати попадут в /tmp/log.txt
распечатать "Тестовая запись 1"
распечатать "Тестовая запись 2"
# вернуться к обычному стандартному выводу
print "Вернуться к нормальному стандартному выводу снова"
И, наконец, еще один пример, который создает временную папку и очищает ее при выходе из контекста:
from tempfile import mkdtemp
из shutil import rmtree
@contextmanager
def временный_каталог (* аргументы, ** kwds):
имя = mkdtemp (* аргументы, ** kwds)
пытаться:
название урожая
наконец:
шутил.rmtree (имя)
с временным_dir () в качестве имени каталога:
# делай что хочешь
Я бы посоветовал две интересные лекции:
1.
Оператор with
используется для того, чтобы обернуть выполнение блока методами, определенными менеджером контекста. Это позволяет инкапсулировать общие шаблоны использования try...except...finally
для удобного повторного использования.
2. Вы можете сделать что-то вроде:
with open("foo.txt") as foo_file:
data = foo_file.read()
OR
from contextlib import nested
with nested(A(), B(), C()) as (X, Y, Z):
do_something()
OR (Python 3.1)
with open('data') as input_file, open('result', 'w') as output_file:
for line in input_file:
output_file.write(parse(line))
OR
lock = threading.Lock()
with lock:
# Critical section of code
3.
Я не вижу здесь никакого антипаттерна.
Цитирую Погружение в Python:
try...finally - хорошо. with - лучше.
4.
Полагаю, это связано с привычкой программистов использовать оператор try..catch..finally
из других языков.
Оператор Python with
является встроенной языковой поддержкой идиомы Resource Acquisition Is Initialization
широко используемой в C++. Она предназначена для безопасного получения и освобождения ресурсов операционной системы.
Оператор with
создает ресурсы внутри области видимости/блока. Вы пишете свой код, используя ресурсы внутри блока. При выходе из блока ресурсы освобождаются независимо от результатов работы кода в блоке (то есть, вышел ли блок нормально или из-за исключения).
Многие ресурсы в библиотеке Python подчиняются протоколу, требуемому оператором with
, и поэтому могут использоваться с ним "из коробки". Однако любой может создать ресурсы, которые могут быть использованы в операторе with, реализуя хорошо документированный протокол: PEP 0343
Используйте его всякий раз, когда вы получаете в своем приложении ресурсы, которые должны быть явно переданы, такие как файлы, сетевые соединения, блокировки и тому подобное.
Примером антипаттерна может быть использование с
внутри цикла, когда было бы более эффективно иметь с
вне цикла
например
for row in lines:
with open("outfile","a") as f:
f.write(row)
vs
with open("outfile","a") as f:
for row in lines:
f.write(row)
Первый способ - это открытие и закрытие файла для каждой строки
, что может вызвать проблемы с производительностью по сравнению со вторым способом, когда файл открывается и закрывается только один раз.
Опять же для полноты картины добавлю свой самый полезный случай использования with
утверждений.
Я много занимаюсь научными вычислениями и для некоторых видов деятельности мне нужна библиотека Decimal
для вычислений произвольной точности. В некоторых частях моего кода мне нужна высокая точность, а в большинстве других частей - меньшая.
Я устанавливаю точность по умолчанию на низкое число, а затем использую with
, чтобы получить более точный ответ для некоторых секций:
from decimal import localcontext
with localcontext() as ctx:
ctx.prec = 42 # Perform a high precision calculation
s = calculate_something()
s = +s # Round the final result back to the default precision
Я часто использую это в гипергеометрическом тесте, который требует деления больших чисел, образующих факториал. Когда вы делаете вычисления в геномном масштабе, нужно быть осторожным с ошибками округления и переполнения.
пункты 1, 2 и 3 достаточно хорошо освещены:
4: он относительно новый, доступен только в python2.6 + (или python2.5 с использованием из __future__ import with_statement
])
Оператор with работает с так называемыми диспетчерами контекста:
http://docs.python.org /release/2.5.2/lib/typecontextmanager.html
Идея состоит в том, чтобы упростить обработку исключений, выполнив необходимую очистку после выхода из блока 'with'. Некоторые встроенные модули Python уже работают как менеджеры контекста.
См. PEP 343 - Оператор «with» , в конце есть пример раздела.
... новый оператор "with" в Python язык сделать можно исключить стандартные варианты использования операторов try / finally.