Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Underscores in Python

3e45c02f2ae5f812a55c4975124da6b2?s=47 Xuanyi
August 22, 2017

Underscores in Python

Underscores don't have meanings (for the most part) in python. But we often give it meaning by convention. In this talk I explore the uses of underscores in Python.

This was presented at Sydney Python for August 2017. It was mostly presented on the terminal, and the code has been copied into a slide for clarity

3e45c02f2ae5f812a55c4975124da6b2?s=128

Xuanyi

August 22, 2017
Tweet

Transcript

  1. _ @chewxy #SyPy August 2017 Follow @chewxy on Twi<er. Tweet

    #sypy. It's mandatory
  2. _ def foo(): return 1, 2.0, "hello", [3,4,5], (6,7) _,

    x, _, y_, _, _ = foo() # x = 2.0 # y = [3,4,5] Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  3. _ Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory

  4. _name _x = "internal use only" Follow @chewxy on Twi<er.

    Tweet #sypy. It's mandatory
  5. _name class Foo: def __init__(self, x): self._x = x >>>

    f = Foo(1) >>> f._x # still accessible! 1 Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  6. _name A Gotcha: In mypkg.py: _x = "internal use only"

    x = "externally accessible variable" Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  7. _name A Gotcha: In mypkg.py: _x = "internal use only"

    x = "externally accessible variable" >>> from mypkg import * >>> x 'externally accessible variable' Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  8. _name A Gotcha: In mypkg.py: _x = "internal use only"

    x = "externally accessible variable" >>> from mypkg import * >>> x 'externally accessible variable' >>> _x Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name '_x' is not defined Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  9. _name A Gotcha: In mypkg.py: _x = "internal use only"

    x = "externally accessible variable" >>> from mypkg import * >>> x 'externally accessible variable' >>> _x Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name '_x' is not defined Avoid this! Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  10. __name DANGER ZONE Follow @chewxy on Twi<er. Tweet #sypy. It's

    mandatory
  11. __name class Foo: def __init__(self, x): self.__x = x Follow

    @chewxy on Twi<er. Tweet #sypy. It's mandatory
  12. __name class Foo: def __init__(self, x): self.__x = x >>>

    f = Foo(1) >>> f.__x Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  13. __name class Foo: def __init__(self, x): self.__x = x >>>

    f = Foo(1) >>> f.__x Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute '__x' >>> Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  14. __name class Foo: def __init__(self, x): self.__x = x >>>

    f = Foo(1) >>> f.__x Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute '__x' >>> WTF IS GOING ON?? Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  15. __name class Foo: def __init__(self, x): self.__x = x >>>

    f = Foo(1) >>> dir(f) ['_Foo__x', '__class__', '__dela<r__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__geta<ribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__seta<r__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] >>> Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  16. __name class Foo: def __init__(self, x): self.__x = x >>>

    f = Foo(1) >>> dir(f) ['_Foo__x', '__class__', '__dela<r__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__geta<ribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__seta<r__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] >>> Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  17. __name class Foo: def __init__(self, x): self.__x = x >>>

    f = Foo(1) >>> f._Foo__x 1 Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  18. __name class Foo: def __init__(self, x): self.__x = x def

    get_x(self): return self.__x >>> f = Foo("SyPy") >>> f.get_x() 'SyPy' >>> f.__x Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute '__x' Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  19. __name class Foo: def __init__(self, x): self.__x = x >>>

    f = Foo(1) >>> dir(f) ['_Foo__x', '__class__', '__dela<r__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__geta<ribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__seta<r__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] >>> Name Mangling Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  20. Why Mangle Names? class Foo: def __init__(self, x): self.__x =

    x class Bar(Foo): def __init__(self, x): super().__init__(x+"1337") self.__x = x >>> b = Bar("SyPy") >>> dir(b) Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  21. Why Mangle Names? class Foo: def __init__(self, x): self.__x =

    x class Bar(Foo): def __init__(self, x): super().__init__(x+"1337") self.__x = x >>> b = Bar("SyPy") >>> dir(b) ['_Bar__x', '_Foo__x', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  22. Why Mangle Names? class Foo: def __init__(self, x): self.__x =

    x class Bar(Foo): def __init__(self, x): super().__init__(x+"1337") self.__x = x >>> b = Bar("SyPy") >>> dir(b) ['_Bar__x', '_Foo__x', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  23. Why Mangle Names? class Foo: def __init__(self, x): self.__x =

    x class Bar(Foo): def __init__(self, x): super().__init__(x+"1337") self.__x = x >>> b = Bar("SyPy") >>> b._Bar__x 'SyPy' >>> b._Foo__x 'SyPy1337' Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  24. Name Mangling NaughZness _Foo__x = 'SyPy still rocks' class Foo:

    def get_x(self): return __x >>> f = Foo() Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  25. Name Mangling NaughZness _Foo__x = 'SyPy still rocks' class Foo:

    def get_x(self): return __x >>> f = Foo() >>> f.get_x() 'SyPy still rocks' Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  26. Name Mangling NaughZness _Foo__x = 'SyPy still rocks' class Foo:

    def get_x(self): return __x >>> f = Foo() >>> f.get_x() 'SyPy still rocks' Python will mangle any name that starts with __ Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  27. __name__ Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory

  28. __name__ class Foo: def __init__(self, x): self.x = x def

    __add__(self, other): return self.x + other >>> f = Foo(1) >>> f + 1 2 Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  29. AutomaZc DifferenZaZon class Value(object): def __init__(self, v, d): self.v =

    v self.d = d def __mul__(self, other): other = promote(other) return Value(self.v * other.v, self.d*other.v + self.v*other.d) def __rmul__(self, other): return Constant(other) * self def __repr__(self): return repr(self.v) def promote(value): return value if isinstance(value, Value) else Value(value,1) Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  30. AutomaZc DifferenZaZon For context: d(x2)/dx = 2x >>> x =

    promote(3) >>> y = x * x >>> y 9 >>> y.d 6 With a bit more jiggering you get full proper automaZc parZal derivaZves Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory
  31. THE END Follow @chewxy on Twi<er. Tweet #sypy. It's mandatory