Почему я не могу вызвать функцию внутри модуля python без полного имени? [Дубликат]

Если у вас возникли проблемы с отправкой писем с помощью PHP, рассмотрите альтернативу, например PHPMailer или SwiftMailer .

Обычно я использую SwiftMailer всякий раз, когда мне нужно для отправки писем с PHP.


Основное использование:

require 'mail/swift_required.php';

$message = Swift_Message::newInstance()
    // The subject of your email
    ->setSubject('Jane Doe sends you a message')
    // The from address(es)
    ->setFrom(array('jane.doe@gmail.com' => 'Jane Doe'))
    // The to address(es)
    ->setTo(array('frank.stevens@gmail.com' => 'Frank Stevens'))
    // Here, you put the content of your email
    ->setBody('

New message

Here goes the rest of my message

', 'text/html'); if (Swift_Mailer::newInstance(Swift_MailTransport::newInstance())->send($message)) { echo json_encode([ "status" => "OK", "message" => 'Your message has been sent!' ], JSON_PRETTY_PRINT); } else { echo json_encode([ "status" => "error", "message" => 'Oops! Something went wrong!' ], JSON_PRETTY_PRINT); }

Подробнее о том, как использовать SwiftMailer, см. в официальной документации .

636
задан varikin 3 March 2016 в 18:52
поделиться

9 ответов

Это список общедоступных объектов этого модуля, интерпретируемых import *. Он отменяет умолчание, скрывая все, что начинается с подчеркивания.

322
ответ дан Jimmy 21 August 2018 в 12:13
поделиться
  • 1
    Объекты, начинающиеся с подчеркивания или не упомянутые в __all__, если __all__ присутствует, не совсем скрыты; их можно увидеть и получить доступ совершенно нормально, если вы знаете их имена. Только в случае «import *», который не рекомендуется в любом случае, это различие несет любой вес. – Brandon Rhodes 8 December 2009 в 19:40
  • 2
    @BrandonRhodes: это не совсем так: рекомендуется только импортировать модули, которые, как вы знаете, предназначены для import * (например, tk). Хороший намек, если это так, - наличие __all__ или имен, начинающихся с подчеркивания в коде модуля. – flying sheep 7 April 2012 в 23:15
  • 3
    Публичные и внутренние интерфейсы - python.org/dev/peps/pep-0008/#id50 . Чтобы лучше поддерживать интроспекцию, модули должны явно объявлять имена в своем открытом API с помощью атрибута __all__. Установка __all__ в пустой список указывает, что модуль не имеет открытого API. – toc 10 April 2018 в 15:20
108
ответ дан Aaron Hall 21 August 2018 в 12:13
поделиться

__all__ настраивает звездочку в from <module> import *

__all__ настраивает звездочку в from <package> import *


Модуль - это файл .py, предназначенный для импорта.

Пакет - это каталог с файлом __init__.py. Пакет обычно содержит модули.

""" cheese.py """

__all__ = ['swiss', 'cheddar']

swiss = 4.99
cheddar = 3.99
gouda = 10.99

__all__ позволяет людям знать «общедоступные» функции модуля. [ @AaronHall ] Также pydoc распознает их. [ @Longpoke ]

из модуля import *

Посмотрите, как swiss и cheddar приведены в локальное пространство имен, но не gouda:

>>> from cheese import *
>>> swiss, cheddar
(4.99, 3.99)
>>> gouda
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'gouda' is not defined

Без __all__ был бы доступен любой символ (который не начинается с подчеркивания).


Импорт без * не зависит от __all__


import module

>>> import cheese
>>> cheese.swiss, cheese.cheddar, cheese.gouda
(4.99, 3.99, 10.99)

из module import names

>>> from cheese import swiss, cheddar, gouda
>>> swiss, cheddar, gouda
(4.99, 3.99, 10.99)

import module as localname

>>> import cheese as ch
>>> ch.swiss, ch.cheddar, ch.gouda
(4.99, 3.99, 10.99)

В файле __init__.py пакета __all__ представлен список строк с именами общедоступных модулей или других объектов. Эти функции доступны для импорта подстановочных знаков. Как и в модулях, __all__ настраивает * при импорте подстановочных знаков из пакета. [ @MartinStettner ]

Вот выдержка из Python MySQL Connector __init__.py:

__all__ = [
    'MySQLConnection', 'Connect', 'custom_error_exception',

    # Some useful constants
    'FieldType', 'FieldFlag', 'ClientFlag', 'CharacterSet', 'RefreshOption',
    'HAVE_CEXT',

    # Error handling
    'Error', 'Warning',

    ...etc...

    ]

Импортировать подстановочные знаки ... следует избегать, поскольку они [путают] считыватели и многие автоматизированные инструменты.

[ PEP 8 , @ToolmakerSteve]

19
ответ дан Bob Stein 21 August 2018 в 12:13
поделиться

Короткий ответ

__all__ влияет на операторы from <module> import *.

Длинный ответ

Рассмотрим этот пример:

foo
├── bar.py
└── __init__.py

В foo/__init__.py:

  • (Неявный) Если мы не определим __all__, тогда from foo import * будет импортировать имена, определенные в foo/__init__.py.
  • (Явно) Если мы определим __all__ = [], то from foo import * ничего не импортирует.
  • (Явно) Если мы определим __all__ = [ <name1>, ... ], тогда from foo import * будет импортировать только эти имена.

Обратите внимание, что в неявном случае python не будет импортировать имена, начинающиеся с _. Однако вы можете принудительно импортировать такие имена с помощью __all__.

Здесь вы можете просмотреть документ Python здесь .

2
ответ дан Cyker 21 August 2018 в 12:13
поделиться

Он также изменяет то, что pydoc покажет:

module1.py

a = "A"
b = "B"
c = "C"

module2.py

__all__ = ['a', 'b']

a = "A"
b = "B"
c = "C"

$ pydoc module1

Help on module module1:

NAME
    module1

FILE
    module1.py

DATA
    a = 'A'
    b = 'B'
    c = 'C'

$ pydoc module2

Help on module module2:

NAME
    module2

FILE
    module2.py

DATA
    __all__ = ['a', 'b']
    a = 'A'
    b = 'B'

Я объявляю __all__ во всех моих модулях, а также подчеркивая внутренние детали, это действительно помогает при использовании вещей, которые вы никогда раньше не использовали живые интерпретаторы.

83
ответ дан L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ 21 August 2018 в 12:13
поделиться

Я просто добавляю это, чтобы быть точным:

Все остальные ответы относятся к модулям . Исходный вопрос явно упоминается __all__ в файлах __init__.py, поэтому речь идет о пакетах python .

Как правило, __all__ входит в игру только тогда, когда вариант from xxx import * оператора import. Это относится как к пакетам, так и к модулям.

Поведение для модулей объясняется в других ответах. Точное поведение для пакетов описано здесь здесь .

Короче говоря, __all__ на уровне пакета делает примерно то же самое, что и для модулей, за исключением того, что он имеет дело с модулей внутри пакета (в отличие от указания имен в модуле ). Таким образом, __all__ указывает все модули, которые должны быть загружены и импортированы в текущее пространство имен, когда мы используем from package import *.

Большая разница в том, что когда вы опускаете , декларация __all__ в пакете __init__.py, инструкция from package import * вообще ничего не импортирует (с исключениями, описанными в документации, см. ссылку выше).

С другой стороны, если вы опускаете __all__ в модуле, «избранный импорт» будет импортировать все имена (не начиная с подчеркивания), определенные в модуле.

135
ответ дан MartinStettner 21 August 2018 в 12:13
поделиться
  • 1
    from package import * все равно будет импортировать все, что определено в __init__.py, даже если нет all. Важным отличием является то, что без __all__ он не будет автоматически импортировать любые модули, определенные в каталоге пакета. – Nikratio 20 July 2014 в 20:37

__all__ используется для документирования открытого API модуля Python. Хотя это необязательно, необходимо использовать __all__.

Вот соответствующая выдержка из ссылки на язык языка Python :

Публичные имена определяемые модулем, определяются путем проверки пространства имен модуля для переменной с именем __all__; если определено, это должна быть последовательность строк, которые являются именами, определенными или импортированными этим модулем. Имена, указанные в __all__, считаются общедоступными и должны существовать. Если __all__ не определен, набор общедоступных имен включает все имена, найденные в пространстве имен модуля, которые не начинаются с символа подчеркивания ('_'). __all__ должен содержать весь открытый API. Он предназначен для того, чтобы случайно не экспортировать элементы, которые не являются частью API (например, библиотечные модули, которые были импортированы и использованы в модуле).

PEP 8 использует аналогичную формулировку, хотя также ясно, что импортированные имена не являются частью общедоступного API, когда __all__ отсутствует:

Чтобы лучше поддерживать интроспекцию, модули должны явно объявлять имена в своих открытый API, используя атрибут __all__. Установка __all__ в пустой список указывает, что модуль не имеет открытого API.

[...]

Импортированные имена всегда должны рассматриваться как детали реализации. Другие модули не должны полагаться на косвенный доступ к таким импортированным именам, если они не являются явно документированной частью API-модуля содержащего модуля, например os.path или модуля __init__ пакета, который предоставляет функции из подмодулей.

Кроме того, как указано в других ответах, __all__ используется для включения подстановочных знаков для пакетов :

Оператор import использует следующее соглашение: если код __init__.py пакета определяет список с именем __all__, он считается списком имен модулей, которые должны быть импортированы, когда встречается from package import *.

7
ответ дан Mihai Capotă 21 August 2018 в 12:13
поделиться

Связано с, но явно не упомянуто здесь, точно, когда используется __all__. Это список строк, определяющих, какие символы в модуле будут экспортироваться, когда from <module> import * используется в модуле.

Например, следующий код в foo.py явно экспортирует символы bar и baz:

__all__ = ['bar', 'baz']

waz = 5
bar = 10
def baz(): return 'baz'

Затем эти символы можно импортировать следующим образом:

from foo import *

print bar
print baz

# The following will trigger an exception, as "waz" is not exported by the module
print waz

Если комментарий __all__ выше, этот код будет выполняться в завершение, поскольку поведение по умолчанию import * заключается в том, чтобы импортировать все символы, которые не начинаются с подчеркивания, из заданного пространства имен.

Ссылка: https://docs.python.org/ 3.5 / tutorial / modules.html # importing-from-a-package

ПРИМЕЧАНИЕ. __all__ влияет только на поведение from <module> import *. Члены, которые не упомянуты в __all__, все еще доступны извне модуля и могут быть импортированы с помощью from <module> import <member>.

680
ответ дан Parag Tyagi -morpheus- 21 August 2018 в 12:13
поделиться

Из (Неофициальный) Справочник по видам Python :

Публичные имена, определенные модулем, определяются путем проверки пространства имен модуля для переменной с именем __all__ ; если определено, это должна быть последовательность строк, которые являются именами, определенными или импортированными этим модулем. Имена, приведенные в __all__, считаются общедоступными и должны существовать. Если __all__ не определен, набор общедоступных имен включает все имена, найденные в пространстве имен модуля, которые не начинаются с символа подчеркивания («_»). __all__ должен содержать весь открытый API. Он предназначен для предотвращения случайного экспорта элементов, которые не являются частью API (например, библиотечные модули, которые были импортированы и использованы в модуле).

49
ответ дан Pavol Babincak 21 August 2018 в 12:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: