2012-06-13 2 views
8

Есть ли функция в стандартной библиотеке Python для воспроизведения схемы преобразования имени Python с именем «private»? Похоже, было бы, но я не могу найти его для жизни.Функция управления именами Python

Я написал это, но если есть лучший способ, я все уши.

def mangle_name (cls, attrname) : 
    prefix = '_' + cls.__name__.lstrip('_') 

    if not attrname.startswith('__') : 
     attrname = '__' + attrname 

    if not attrname.endswith('__') : 
     return prefix + attrname 
    else : 
     return attrname 

class Foo : 
    __some_such = 3 

name = mangle_name(Foo, '__some_such') 
print name 
print hasattr(Foo(), name) 
+3

Я уверен, что нет такой функции в стандартная библиотека. Для чего тебе это? –

+8

Я могу себе представить, что это почти всегда будет использоваться, чтобы что-то сделать плохо. –

+0

В принципе, мне нужно динамически обращаться к частным атрибутам произвольного класса. Функция выше работает; однако, с этим могут возникнуть проблемы, о которых я не знаю (какая-то непредвиденная проблема). Таким образом, использование чьего-то другого похоже на лучший вариант. – rectangletangle

ответ

14

Похоже compiler модуль имеет реализация Python для этого, подпись mangle(name, klass) где klass это имя класса, а не сам объект.

Вот как вы можете получить доступ и использовать его:

>>> from compiler.misc import mangle 
>>> mangle('__some_such', 'Foo') 
'_Foo__some_such' 

Обратите внимание, что модуль компилятора устаревшее, поскольку Python 2.6 и не существует в Python 3.0.

Вот сама (из Python 2.7 source code) функции в случае, если вы просто хотите, чтобы скопировать его в источник или убедитесь, что ваша версия эквивалентна:

MANGLE_LEN = 256 # magic constant from compile.c 

def mangle(name, klass): 
    if not name.startswith('__'): 
     return name 
    if len(name) + 2 >= MANGLE_LEN: 
     return name 
    if name.endswith('__'): 
     return name 
    try: 
     i = 0 
     while klass[i] == '_': 
      i = i + 1 
    except IndexError: 
     return name 
    klass = klass[i:] 

    tlen = len(klass) + len(name) 
    if tlen > MANGLE_LEN: 
     klass = klass[:MANGLE_LEN-tlen] 

    return "_%s%s" % (klass, name) 
+0

Это работает, спасибо! – rectangletangle

+1

Нет ли замены stdlib в Python 3? Мне кажется, что нам лучше использовать библиотечную функцию, если кто-то использует другое значение, чем 256. Например, что используют PyPy, Jython и IronPython? – asmeurer

Смежные вопросы