Inheriting class attribute with double underscore

前端 未结 2 396
暗喜
暗喜 2021-01-24 05:04

I think I understand the concept of \"name mangling\" in python, but there\'s something that I probably missed. Take a look at the following code:

#!/usr/bin/env         


        
2条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-24 06:02

    You are not "missing", to the contrary, you just "found out" what name mangling does: it is made to ensure variables with double underscores inside a method will always see the attribute defined in the same class as that method, and in none of its subclasses.

    If you simply want to use the attribute as it is overriden in each subclass, that is the normal behavior for all other attributes, but for the ones prefixed by two underscores.

    So, what happens is that the .__data name used inside func is itself mangled, at compile time, to _base__data.

    OrderedDict

    Python's collections.OrderedDict have an extra trap: Python offers both a pure-python implementation, which uses the __ for its "private attributes", as explained above, but also have a native code implementation in C, and the private structures of that are not exposed to Python.

    And the collections module ends the OrderedDict code block with these lines:

    try:
        from _collections import OrderedDict
    except ImportError:
        # Leave the pure Python version in place.
        pass
    

    That is: the normal "collections.OrderedDict" is written in C, with a lot of opaque structures, that can't be tapped in by subclasses.

    The only way to have access to the Python defined OrderedDict is by deleting the _collections.OrderedDict attribute (in the _collections, not collections module), and reload the collections module.

    If you do that, and instantiate one ordered dict, the private data structures can be seem:

    
    from imp import reload
    import _collections, collections
    backup = _collections.OrderedDict
    del _collections.OrderedDict
    collections = reload(collections)
    PyOrderedDict = collections.OrderedDict
    _collections.OrderedDict = backup
    a  = PyOrderedDict()
    dir(a)
    
    Out[xx]: 
    ['_OrderedDict__hardroot',
     '_OrderedDict__map',
     '_OrderedDict__marker',
     '_OrderedDict__root',
     '_OrderedDict__update',
     '__class__',
     '__contains__',
     '__delattr__',
     ...
    ]
    

提交回复
热议问题