Ich möchte eine Python-Codierungstechnik vorstellen, die ich nicht viel gesehen habe. Es tut mir leid, wenn es unerwartet groß ist. Ich möchte so viel Beispielcode wie möglich einfügen, um zu zeigen, wie es tatsächlich funktioniert. Da es Nischentechnologien zusammenfasst, wird davon ausgegangen, dass Sie Python in gewissem Umfang schreiben können.
functools.partial
Sie können dies verwenden, um ** eine Funktion mit festen Argumenten ** für eine Funktion zu erstellen. Ich denke, es ist schneller, sich den Code anzusehen.
import functools
def add(x, y):
return x + y
add_fixed_y = functools.partial(add, y=5)
print(add_fixed_y(2)) # 7
Ich weiß nicht, wofür dies allein nützlich sein wird, daher möchte ich meine eigene Verwendung vorstellen. Ich benutze es für die ** open
Funktion ** der Datei.
open_utf_8 = functools.partial(open, encoding="utf-8")
r_open_utf_8 = functools.partial(open_utf_8, mode="r")
w_open_utf_8 = functools.partial(open_utf_8, mode="w")
with w_open_utf_8("something_great.txt") as wf:
wf.write("Hello World!")
Auf diese Weise können Sie die Konstanten innerhalb des Codes reduzieren und den Tippfehler im Codierungsteil verhindern.
next
und GeneratorDie Ausdrücke in der Listeneinschlussnotation können für Generatorausdrücke verwendet werden, und das Erstellen von Generatorobjekten wurde in anderen Artikeln eingeführt.
gen = (i ** 2 for i in range(10))
print(gen) # <generator object <genexpr> at 0x~~>
Wie ist dies bei der eigentlichen Codierung nützlich? Ich benutze es, um den ersten Index ** zu finden, der die ** Kriterien erfüllt. Es wird zum ** Runden der Zeichenfolge auf die angegebene Anzahl von Bytes oder weniger ** verwendet.
from itertools import accumulate
def str_clamp_bytes(value: str, max_bytes: int) -> str:
byte_count = (len(s.encode("utf-8")) for s in value)
try:
end_slice = next(i for i, v in enumerate(accumulate(byte_count)) if v > max_bytes)
except StopIteration:
return value
return value[:end_slice]
(i für i, v in enumerate (akkumulieren (byte_count)) wenn v> max_bytes)
ist der Generator und wenn v> max_bytes
der bedingte Ausdruck ist. end_slice
wird der erste Index zugewiesen, der v> max_bytes
erfüllt. Wenn es keinen Index gibt, der die Bedingungen erfüllt, tritt eine StopIteration-Ausnahme auf. Fangen Sie ihn also ab und geben Sie die ursprüngliche Zeichenfolge zurück. Der Generator ist ausreichend, da "byte_count" nur für "akkumulieren" verwendet wird.
__debug__
Diese Variable wird zu "False", wenn beim Start die Option "-O" (nicht Null) hinzugefügt wird. Wenn Sie die Option "-O" hinzufügen, wird die Anweisung "assert" ungültig und Sie können das Programm beschleunigen, sodass Sie es problemlos in der Produktversion hinzufügen können. Ich benutze es für den Prozess der ** Lieferung nur der Produktversion **.
def broadcast_debug():
pass
def broadcast_prod():
pass
(broadcast_debug if __debug__ else broadcast_prod)()
lru_cache
DekorateurWenn Sie sich das Funktionsargument / Rückgabewert-Paar im Wörterbuch merken, gibt das zuvor übergebene Argument den vorherigen Rückgabewert ohne Verarbeitung zurück.
from functools import lru_cache
@lru_cache
def fib(n):
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
print(fib(10))
Da es sich um ein Wörterbuch handelt, ist die Zugriffsgeschwindigkeit schlechter als beim reinen Schreiben von Memos, aber die Benutzerfreundlichkeit ist großartig. Danach kann es auch dann behandelt werden, wenn ** Zeichenfolgen usw. als Argumente ** verwendet werden, die durch die Memokonvertierung nicht behandelt werden können.
inspect.getmembers
Sie können ** alle Mitglieder aus dem Modul holen **. Sie können den Elementtyp mit dem zweiten Argument angeben.
import inspect
import copy
print(inspect.getmembers(copy, inspect.isclass))
# >> [('Error', <class 'copy.Error'>), ('error', <class 'copy.Error'>)]
** Sie können alle Klassen aus dem Modul extrahieren **, sodass Sie sie alle auf einmal abrufen können, ohne den Aufwand von "load_classes = [class_A, class_B, ...]". Und Sie müssen nicht vergessen, es hinzuzufügen. Das Klassenobjekt hat ein "bases" -Mitglied, und alle geerbten Klassenobjekte sind als Tapples enthalten. Ich denke, Sie können diesen Bereich zum Filtern verwenden.
Ich habe einen Trick eingeführt, den ich für "praktisch, aber ich sehe nicht viel" halte. Bitte lassen Sie mich wissen, wenn Sie Fehler oder Tippfehler haben.
Recommended Posts