12

「プライベート」属性名でPythonの名前マングリングスキームを再現する関数が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)
4

1 に答える 1

17

コンパイラモジュールには、このための 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 ソース コードから) 以下に示します。

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)
于 2012-06-13T23:05:04.680 に答える