Определение частных функций модуля в python
согласно http://www.faqs.org/docs/diveintopython/fileinfo_private.html:
как и большинство языков, Python имеет понятие частных элементов:
- частная функции, которые не могут быть вызваны из вне их модуля
однако, если я определяю два файла:
#a.py
__num=1
и:
#b.py
import a
print a.__num
когда я запускаю b.py
выводит 1
без каких-либо исключений. Это diveintopython неправильно, или я что-то неправильно понял? И есть ли какой-то способ сделать определить функцию модуля как частный?
8 ответов:
в Python "конфиденциальность" зависит от уровня согласия" согласных взрослых " - вы не можете силу он (больше, чем вы можете в реальной жизни;-). Одно начальное подчеркивание означает, что вы не должно чтобы получить доступ к нему "извне"-- два начальные подчеркивания (без конечных подчеркиваний) несут сообщение еще более сильно... но, в конце концов, это все еще зависит от социальной конвенции и консенсуса: самоанализ Python достаточно силен, чтобы вы не могу наручники каждый другой программист в мире, чтобы уважать ваши пожелания.
((кстати, хотя это очень секретно, почти то же самое относится и к C++: с большинством компиляторов простой
#define private public
строка перед#include
ваша.h
файл-это все, что нужно для хитрых кодеров, чтобы сделать хэш вашей "конфиденциальности"...!- ))
может быть путаница между класс приваты и модуль рядового.
A модуль частного начинается с один символ подчеркивания
Такой элемент не копируется вместе при использованииfrom <module_name> import *
форма команды импорта; однако она импортируется при использованииimport <moudule_name>
синтаксис ( смотрите ответ Бена Вильгельма)
Просто удалите один символ подчеркивания из a.__num пример вопроса, и он не будет отображаться в модулях, которые импортируют a.py используяfrom a import *
синтаксис.A класс private начинается с два подчеркивания (Дандер ака например, двойного под-счет)
Такая переменная имеет свое имя "mangled", чтобы включить имя класса и т. д.
Он все еще может быть доступен вне логики класса, через искаженное имя.
Хотя имя mangling может служить как слабый прибор предохранения против несанкционированного доступа, свое основная цель состоит в том, чтобы предотвратить возможные столкновения имен с членами класса классов-предков. Смотрите забавную, но точную ссылку Алекса Мартелли на взрослые как он описывает соглашение, используемое в отношении этих переменных.>>> class Foo(object): ... __bar = 99 ... def PrintBar(self): ... print(self.__bar) ... >>> myFoo = Foo() >>> myFoo.__bar #direct attempt no go Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute '__bar' >>> myFoo.PrintBar() # the class itself of course can access it 99 >>> dir(Foo) # yet can see it ['PrintBar', '_Foo__bar', '__class__', '__delattr__', '__dict__', '__doc__', '__ format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__ ', '__subclasshook__', '__weakref__'] >>> myFoo._Foo__bar #and get to it by its mangled name ! (but I shouldn't!!!) 99 >>>
на этот вопрос не был полностью дан ответ, так как конфиденциальность модуля не является чисто обычной, а с использованием импорт может или не может распознавать конфиденциальность модуля, в зависимости от того, как он используется.
если вы определяете частные имена в модуле, эти имена будет импортируется в любой скрипт, который использует синтаксис, 'import module_name'. Таким образом, предполагая, что вы правильно определили в своем примере модуль private, _num, in a.py например так..
#a.py _num=1
..вы сможете получить к нему доступ b.py с символом имени модуля:
#b.py import a ... foo = a._num # 1
импортировать только неприватизированных из a.py, вы должны использовать С синтаксис:
#b.py from a import * ... foo = _num # throws NameError: name '_num' is not defined
для ясности, однако, лучше быть явным при импорте имена из модулей, а не импортировать их все с '*':
#b.py from a import name1 from a import name2 ...
Python позволяет использовать private класс члены с двойным префиксом подчеркивания. Этот метод не работает на уровне модуля, поэтому я думаю, что это ошибка в погружении в Python.
вот пример частных функций класса:
class foo(): def bar(self): pass def __bar(self): pass f = foo() f.bar() # this call succeeds f.__bar() # this call fails
Это древний вопрос, но как частные модули (одно подчеркивание), так и частные классы (два подчеркивания) искаженные переменные теперь рассматриваются в стандартной документации:
вы можете добавить внутреннюю функцию:
def public(self, args): def private(self.root, data): if (self.root != None): pass #do something with data
что-то вроде этого, если вам действительно нужен такой уровень конфиденциальности.
врезанный с закрытиями или функциями один путь. Это распространено в JS, хотя и не требуется для не-браузерных платформ или рабочих браузеров.
в Python это кажется немного странным, но если что-то действительно нужно скрыть, чем это может быть путь. Более того, использование API python и сохранение вещей, которые требуют скрытия в C (или другом языке), вероятно, лучший способ. В противном случае я бы пошел на то, чтобы поместить код внутри функции, вызывая это и имея он возвращает элементы, которые вы хотите экспортировать.