@ Pythonetc November 2018


Dies ist die sechste Sammlung von Python-Tipps und -Programmierungen aus meinem @ pythonetc-Feed.

Vorherige Auswahl:



Atypische Dekorateure


Funktionsdekorateure müssen nicht nur neue Funktionen zurückgeben, sondern können jeden anderen Wert zurückgeben:

def call(*args, **kwargs): def decorator(func): return func(*args, **kwargs) return decorator @call(15) def sqr_15(x): return x * x assert sqr_15 == 225 

Dies kann nützlich sein, um einfache Klassen mit nur einer neu definierbaren Methode zu erstellen:

 from abc import ABCMeta, abstractmethod class BinaryOperation(metaclass=ABCMeta): def __init__(self, left, right): self._left = left self._right = right def __repr__(self): klass = type(self).__name__ left = self._left right = self._right return f'{klass}({left}, {right})' @abstractmethod def do(self): pass @classmethod def make(cls, do_function): return type( do_function.__name__, (BinaryOperation,), dict(do=do_function), ) class Addition(BinaryOperation): def do(self): return self._left + self._right @BinaryOperation.make def Subtraction(self): return self._left - self._right 


__length_hint__


Mit PEP 424 können Generatoren und andere iterable Elemente, die keine bestimmte vorgegebene Größe haben, ihre ungefähre Länge zurückgeben. Zum Beispiel wird dieser Generator wahrscheinlich ungefähr 50 Elemente zurückgeben:

 (x for x in range(100) if random() > 0.5) 

Wenn Sie etwas Iterierbares schreiben und eine ungefähre Länge zurückgeben möchten, definieren Sie die Methode __length_hint__ . Und wenn Sie die genaue Länge kennen, verwenden Sie __len__ . Wenn Sie ein iterierbares Objekt verwenden und wissen möchten, wie lange es dauern kann, verwenden Sie operator.length_hint .

in mit Generator


Der Operator in kann mit Generatoren verwendet werden: x in g . In diesem Fall iteriert Python über g bis x oder bis g endet.

 >>> def g(): ... print(1) ... yield 1 ... print(2) ... yield 2 ... print(3) ... yield 3 ... >>> 2 in g() 1 2 True 

range() funktioniert jedoch etwas besser. Es hat eine magisch überschriebene Methode __contains__ , dank derer die rechnerische Komplexität von in gleich O (1) wird:

 In [1]: %timeit 10**20 in range(10**30) 375 ns ± 10.7 ns per loop 

Beachten Sie, dass dies mit der Funktion xrange() von Python 2 nicht funktioniert.

Operatoren + = und +


Python hat zwei verschiedene Operatoren: += und + . Die Methoden __iadd__ und __add__ sind für ihr Verhalten verantwortlich.

 class A: def __init__(self, x): self.x = x def __iadd__(self, another): self.x += another.x return self def __add__(self, another): return type(self)(self.x + another.x) 

Wenn __iadd__ nicht definiert ist, funktioniert a += b als a = a + b .

Der semantische Unterschied zwischen += und + besteht darin, dass der erste das Objekt ändert und der zweite ein neues erstellt:

 >>> a = [1, 2, 3] >>> b = a >>> a += [4] >>> a [1, 2, 3, 4] >>> b [1, 2, 3, 4] >>> a = a + [5] >>> a [1, 2, 3, 4, 5] >>> b [1, 2, 3, 4] 

Funktion als Attribut einer Klasse


Sie können eine Funktion nicht als Klassenattribut speichern, da sie automatisch in eine Methode konvertiert wird, wenn über eine Instanz auf sie zugegriffen wird:

 >>> class A: ... CALLBACK = lambda x: x ** x ... >>> A.CALLBACK <function A.<lambda> at 0x7f68b01ab6a8> >>> A().CALLBACK <bound method A.<lambda> of <__main__.A object at 0x7f68b01aea20>> >>> A().CALLBACK(4) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: <lambda>() takes 1 positional argument but 2 were given 

Sie können die Funktion betrügen und in einen einfachen Deskriptor einschließen:

 >>> class FunctionHolder: ... def __init__(self, f): ... self._f = f ... def __get__(self, obj, objtype): ... return self._f ... >>> class A: ... CALLBACK = FunctionHolder(lambda x: x ** x) ... >>> A().CALLBACK <function A.<lambda> at 0x7f68b01ab950> 

Sie können die Situation auch verlassen, indem Sie die Klassenmethode anstelle des Attributs verwenden.

 class A: @classmethod def _get_callback(cls): return lambda x: x ** x 

Source: https://habr.com/ru/post/de432628/


All Articles