diff --git a/notes-other/pythonetc/assert.md b/notes-other/pythonetc/assert.md new file mode 100644 index 0000000..d8f8f0e --- /dev/null +++ b/notes-other/pythonetc/assert.md @@ -0,0 +1,25 @@ +Basically, `assert` could be a function: + +```python + +def assert_(test, *args): + if not test: + raise AssertionError(*args) + +assert_(2 + 2 == 4, 'the world is broken') +``` + +However, there are few advantages of assert as directive over assert as function: + +1. All asserts removed on the bytecode compilation step if [optimization is enabled](https://t.me/pythonetc/115). + +2. The message is lazy and executed only when needed: + +```python +assert False, print("executed") +# executed +# AssertionError: None + +assert True, print("not executed") +# (prints nothing) +``` diff --git a/notes-other/pythonetc/cached-property.md b/notes-other/pythonetc/cached-property.md new file mode 100644 index 0000000..7398d3b --- /dev/null +++ b/notes-other/pythonetc/cached-property.md @@ -0,0 +1,33 @@ +Decorator `@cached_property` is an amazing way to simplify your code. It's like the regular `@property` but remembers the value after the first call: + +```python +class C: + @cached_property + def p(self): + print('computating...') + return 1 + +c = C() +c.p +# computating... +# 1 + +c.p +# 1 +``` + +The implementation is short and relatively simple: + +``` python +class cached_property: + def __init__(self, func): + self.func = func + + def __get__(self, obj, cls): + if obj is None: + return self + value = obj.__dict__[self.func.__name__] = self.func(obj) + return value +``` + +However, there are a few corner-cases, like async functions and threads. Luckily, from Python 3.8 it's a part of standard library ([functools.cached_property](https://docs.python.org/dev/library/functools.html#functools.cached_property)) and for older versions [cached-propery](https://github.com/pydanny/cached-property) library can be used. diff --git a/notes-other/pythonetc/nan.md b/notes-other/pythonetc/nan.md new file mode 100644 index 0000000..18dcd6b --- /dev/null +++ b/notes-other/pythonetc/nan.md @@ -0,0 +1,20 @@ +Python has [NaN](https://t.me/pythonetc/561) float value and it's a rule-breaking thing: + +```python +import math + +sorted([5.0, math.nan, 10.0, 0.0]) +# [5.0, nan, 0.0, 10.0] + +3 < math.nan +# False +3 > math.nan +# False + +min(3, math.nan) +# 3 +min(math.nan, 3) +# nan +``` + +Be careful. Use `math.isnan` to check if a value is NaN.