Raymond Hettinger

@raymondh

Chief trainer for Mutable Minds. Certified Public Accountant. Python guru. Alloy and TLA⁺ enthusiast. Aspiring pianist. Former pilot. Born at 320 ppm CO₂.

Santa Clara, CA
Joined March 2008

Tweets

You blocked @raymondh

Are you sure you want to view these Tweets? Viewing Tweets won't unblock @raymondh

  1. 22 hours ago

    Your move: 3/ * Reposted with spaces instead of tabs

    Show this thread
    Undo
  2. 22 hours ago

    Let the games begin! >>> d = Dict( cm = classmethod(lambda cls: cls.__name__.upper()), pr = property(lambda self: self['x'] ** 2), x = 5, ) >>> d['cm']() 'DICT' >>> d['pr'] 25 >>> d['x'] = 6 >>> d['pr'] 36 2/

    Show this thread
    Undo
  3. 22 hours ago

    Egregious hack of the day: Add descriptor logic to dictionaries. class Dict(dict): def __getitem__(self, key): value = super().__getitem__(key) if hasattr(value, '__get__'): return value.__get__(self, type(self)) return value 1/

    Show this thread
    Undo
  4. Oct 27

    The @cached_property() decorator only works if there is a writeable instance dictionary, so it won't work with __slots__ or metaclasses. Also the writeback does not play well with PEP 412 key-sharing dicts, so you lose the space savings. 5/

    Show this thread
    Undo
  5. Oct 27

    For cached_property(), being a non-data descriptor is the key to how it works. When it is first called, the result is written back to the instance dictionary. Subsequent calls find the attribute instead of the cached property. 4/

    Show this thread
    Undo
  6. Oct 27

    >>> d = {'__get__', '__set__', '__delete__'} >>> d & set(dir(property)) {'__set__', '__get__', '__delete__'} >>> d & set(dir(lambda : None)) {'__get__'} >>> d & set(dir(classmethod)) {'__get__'} >>> d & set(dir(cached_property)) {'__get__'} 3/

    Show this thread
    Undo
  7. Oct 27

    class A: def p(self): return 'boop' def m(self): return 'pop' >>> a = A() >>> a.p 'boop' >>> a.m() 'pop' >>> vars(a)['p'] = 'hiss' >>> vars(a)['m'] = 'bonk' >>> a.p # instance variable ignored 'boop' >>> a.m # instance variable honored 'bonk' 2/

    Show this thread
    Undo
  8. Oct 27

    tip: A descriptor defining __set__() or __delete__() is considered a data descriptor and has precedence over an instance variable with the same name. property() is a data descriptor. Function, classmethod, staticmethod, and cached_property are non-data descriptors. 1/

    Show this thread
    Undo
  9. Oct 26

    5/ People are always asking about how to kill another thread. We don't provide an API for that. Reason: you never know when that thread is holding a lock. But if you're clever, you can use ctypes to kill it. Afterwards, feel free to contract me for help with the deadlocks. 🥲

    Show this thread
    Undo
  10. Oct 26

    4/ Integers are immutable in , but if you're clever, ctypes can be used to alter the value field. Nothing good can come of this. 🥸

    Show this thread
    Undo
  11. Oct 26

    3/ Once upon a time, True and False weren't keywords. You could write: True, False = False, True and watch the world fall apart. Ultimately, it was decided that constants should be constant. 😇

    Show this thread
    Undo
  12. Oct 26

    2/ Today a Pythonista wanted to how to make "C() is None" always return True, by overriding 's is-operator. correctly advised that this would be "catastrophic". This conversation is still continuing as people look for ways to lie about object identity. 🤔

    Show this thread
    Undo
  13. Oct 26

    1/ Many years ago, I maintained General Ledger software. A customer wanted to know how to disable the debits==credits check. We strongly advised against it. Never the less, the customer demanded to know. A month later, they called back saying their books were out of balance 🧐

    Show this thread
    Undo
  14. Oct 25

    5/ The decorator is new in version 3.9. Prior to that, you can get the same effect with an lru_cache where the maxsize is set to None: (maxsize=None) def f(x): ... So, really is just a pretty way to spell it.

    Show this thread
    Undo
  15. Oct 25

    4/ It's implemented with fast C code, equivalent to: key = make_key(args, kwds, typed) result = cache_get(key, sentinel) if result is not sentinel: hits += 1 return result misses += 1 result = user_function(*args, **kwds) cache[key] = result return result

    Show this thread
    Undo
  16. Oct 25

    3/ Behind the scenes, there is a single dictionary lookup and a counter increment. Some kinds arguments will take longer to hash, but you get the idea, has very little overhead.

    Show this thread
    Undo
  17. Oct 25

    2/ Here are the timings: $ python3.9 -m timeit -r11 -s 'def s(x):pass' 's(5)' 5000000 loops, best of 11: 72.1 nsec per loop $ python3.9 -m timeit -r11 -s 'from functools import cache' -s 'def s(x):pass' -s 'c=cache(s)' 'c(5)' 5000000 loops, best of 11: 60.6 nsec per loop

    Show this thread
    Undo
  18. Oct 25

    1/ tip: The functools.cache() decorator is astonishingly fast. Even an empty function that returns None can be sped-up by caching it. 🤨

    Show this thread
    Undo
  19. Oct 24
    Show this thread
    Undo
  20. Oct 24

    Here's a live draft for the second round of edits. In particular, please look at the new Descriptor Example:

    Show this thread
    Undo

Loading seems to be taking a while.

Twitter may be over capacity or experiencing a momentary hiccup. Try again or visit Twitter Status for more information.

    You may also like

    ·