[Tutor] Naming variables

eryksun eryksun at gmail.com
Sun Jan 19 21:59:49 CET 2014


On Sun, Jan 19, 2014 at 9:21 AM, spir <denis.spir at gmail.com> wrote:
> I guess (not sure) python optimises access of dicts used as scopes (also of
> object attributes) by interning id-strings and thus beeing able to replace
> them by hash values already computed once for interning, or other numeric

A string object caches its hash, but initially it isn't computed (-1).
On the `dict` lookup fast path, you have a cached hash, where the
string wasn't probed to a different table index by a hash collision,
and the string is interned with the same address (CPython ID) as the
key in the table.

CPython setattr is implemented by calling PyObject_SetAttr, which
interns the name. The string will be used by subsequently interned
strings. Code objects intern strings, but those will already have been
instantiated for the module, and we're dealing with dynamic strings
here like `"year" + str(1900)`. That leaves dynamic code that you
compile/exec.

    years = type('Years', (), {})
    setattr(years, 'year' + str(1900), [])
    s1 = next(s for s in vars(years) if s == 'year1900')

Compile a code object containing the string 'year1900' as a constant:

    code = compile('"year1900"', '<string>', 'exec')
    s2 = next(s for s in code.co_consts if s == 'year1900')

The code object interned the string constant because it's all name
characters (ASCII letters, numbers, and underscore):

    >>> s2 is s1
    True

You could also call sys.intern to get the interned string, but it
isn't worth the cost of the call each time:

    >>> s3 = 'year' + str(1900)
    >>> s3 is s1
    False
    >>> s4 = sys.intern(s3)
    >>> s4 is s1
    True

Thankfully a dict with only string keys uses an efficient equality
comparison, so all of this is really a moot point:

http://hg.python.org/cpython/file/3.3/Objects/stringlib/eq.h


More information about the Tutor mailing list