что мне нравится делать, хотя это не совсем на 100% приватно, это использовать замыкания в методах для R / W обычно недоступных атрибутов в качестве объектов member_descriptor:
def privateNS():
class MyObject(object):
__slots__ = ['private'] # name doesn't matter
def __new__(cls, value): # only sets inst.private on new instance creation
inst = object.__new__(cls)
setprivate(inst, value)
return inst
# __init__ is not needed, and can't be used here to set inst.private
def showprivate(inst):
return getprivate(inst)
dsc = MyObject.private # get descriptor
getprivate = dsc.__get__
setprivate = dsc.__set__
del MyObject.private # revoke normal access
return MyObject
MyObject = privateNS()
del privateNS
inst = MyObject( 20 )
print( inst.showprivate() ) # 20
обратите внимание, что имя inst.privateне существует и вызовет AttributeError, если на него ссылаются.но сам дескриптор члена существует и привязан к классу.
но, как я уже сказал, он не на 100% приватен ...Вы можете получить доступ к методам дескриптора, предоставленным методам класса, через их замыкания:
>>> inst.showprivate.__closure__[0].cell_contents
<method-wrapper '__get__' of member_descriptor object at 0x00E588A0>
- это первый бэкдор, если указанный метод содержит __set__
в своих замыканиях.но если нет, 2-й бэкдор только немного сложнее:
>>> inst.showprivate.__closure__[0].cell_contents.__self__.__set__( inst, 30 )
>>> inst.showprivate()
30
что-то помогает, хотя при использовании нескольких замыканий порядок ячеек замыкания зависит от текущего прогона (как ключи словаря).
к сожалению, я не могу понять что-то более безопасное, чем эта ...
проблема в том, как указано в предыдущем ответе:Атрибуты не могут сказать, к чему они обращаются, и предоставление такого уровня функциональности через код Python всегда оставляет их открытыми, потому что они всегда могут быть доступны и изменены.
если я ошибаюсь, пожалуйста, прокомментируйте:)