Hallo. Ich bin Nabeta, eine Softwareentwicklerin in der Infrastrukturgruppe. Es ist die Nacht des 11. (22:00), also schreibe ich diesen Artikel in Eile. Ich werde weiter schreiben, nachdem ich es bis zur letzten Minute gefunden habe. Drücke so ruhig auf die Tastatur, wie du keine Zeit hast, Luke.
Grundsätzlich wartet die Veröffentlichung nur, wenn sie ziemlich gefährlich ist. Ich denke, dass jeder Erfahrung darin hat, sie als "Nein!" An die Welt zu senden. Außerdem konnte ich mir nicht die Zeit nehmen, den vorhandenen Code zu überarbeiten, und ich schrieb einen seltsamen Code, weil ich nicht in der Lage war. Danach werde ich über einige der Muster nachdenken, die ich behoben habe. Wie auch immer, ich habe keine Zeit, also lasst uns unser Bestes tun, um den Platz für Artikel zu füllen!
sample1.py
class Api(object):
def __init__(self, init_data):
self.init_data = init_data
self.prepare()
def prepare(self)
for k, v in self.init_data.items():
self.__data__[k] = v
init_data
ist ein Wörterbuch. Selbst wenn das Innere von "init_data", das von "Api" gegessen wird, geändert wird, muss ich die Implementierung von "Api" nicht ändern, und ich habe es oft verwendet, während ich dachte, es sei metaprogrammierend und cool. Wenn Sie es lesen, müssen Sie die interne Implementierung von init_data
und anderer Klassen und Methoden kennen, die die Verwendung von Api
-Objekten implementieren, was ziemlich schmerzhaft ist. Wenn Sie "init_data" mit Code generieren, ist das Lesen sehr unangenehm.
Es war später einfacher zu lesen, wenn ich ein Wörterbuch vorbereitete, das alle Schlüssel und Werte definierte, oder eine Klasse erstellte, die sie umschließt.
sample2.py
class Api(object):
def __init__(self, init_data):
self.name = name
self.a = init_data['a']
self.b = init_data['b']
...
Mit Python können Sie nach einem Block von Schleifen ein "else" setzen.
sample3.py
for i in range(5):
print('Count %d' % i)
else:
print('ELSE BLOCK!!')
Dies wird unmittelbar nach dem Ende der Schleife ausgeführt. Es gibt überhaupt kein "anderes" Gefühl. Außerdem wird dieser übersprungen, wenn "Pause" gemacht ist, so dass ich die Bedeutung von "Sonst" nicht mehr verstehe.
sample4.py
>>> for i in range(5):
... if i == 3:
... break
... print(i)
... else:
... print('ELSE!') # unreachable!
0
1
2
Dann habe ich mich gefragt, wofür dieser Typ gedacht ist, aber ich denke, es wäre ein wenig effektiv, wenn man etwas verarbeitet, das die Bedingungen in einer Schleife erfüllt. In diesem Fall ist es jedoch einfacher zu lesen, wenn Sie eine Funktion für diesen Zweck erstellen. Der Name "else" ist irreführend und sollte nicht verwendet werden.
Im Folgenden wird das Ergebnis gescannt und zurückgegeben, ob Sie das Gesuchte gefunden haben oder nicht.
sample5.py
#Das ist besser
def power_up_if(users):
found = False
for user in users:
if user == 42: #Kehre zurück, sobald der gesuchte Zustand gefunden wurde
found = True
break
return user, found
users = [1,2,3,41,42,5]
uid, found = power_up_if(users)
if found:
print('uid:', uid, 'is power up!')
Sie möchten selten nicht statische Schlüsselwortargumente als Standardwerte für Funktionen und Methoden verwenden.
sample6.py
>>> def log_out(msg, when=datetime.datetime.now()):
... print('%s %s ' % (when, msg))
...
... log_out('Good bye!!')
... log_out('Good bye!!')
2016-12-11 21:21:20.928785 Good bye!!
2016-12-11 21:21:20.928785 Good bye!!
Ich denke, dies ist eine Spezifikation, die Sie sicherlich kennen (Schritt für Schritt), wenn Sie Python so schreiben, wie es ist. Das Standardargument wird nur einmal ausgewertet, wenn die Funktion definiert ist. Mit anderen Worten, der Wert des Standardarguments wird beim Laden des Moduls bestimmt und nie wieder ausgewertet. Ich bin auch auf diese Spezifikation getreten und habe viel Geld bezahlt, um das Problem zu lösen. Als Workaround
sample7.py
>>> def log_out(msg, when=None):
... """Ausgabeprotokoll mit Zeitstempel
...
... Args:
... msg:Nachricht protokollieren
... when:Datum und Uhrzeit der Protokollausgabe. Wenn nicht, stellen Sie das aktuelle Datum und die aktuelle Uhrzeit ein.
... """
... when = datetime.datetime.now() if when is None else when
... print('%s %s ' % (when, msg))
>>> log_out('hoge')
2016-12-11 21:28:58.293714 hoge
>>> log_out('bye')
2016-12-11 21:29:02.566320 bye
>>> log_out('bye', datetime.datetime(2016,11,1))
2016-11-01 00:00:00 bye
Ich denke, es ist besser, den Wert des Standardarguments auf "None" zu setzen und ihn durch die Redewendung "when = datetime.datetime.now () zu bestimmen, wenn wann None else when" in der Funktion ist. Wenn ja, werde ich es einstellen, und wenn nicht, werde ich es hier tun.
Soweit ich weiß, gibt es in Python kein absolutes Privatleben.
sample8.py
>>> class A(object):
... def __aa(self):
... print('private')
>>>
>>>
>>> a = A()
>>> a._A__aa()
private
>>> class A(object):
... def __init__(self, a):
... self.__a = a
>>>
>>> a = A(123)
>>> print(a.__dict__)
{'_A__a': 123}
Daher kann jeder, der die Konvertierungsregeln des Compilers wie oben beschrieben kennt, auf die privaten Attribute zugreifen. Da jedoch privat und öffentlich als Sichtbarkeit der Klasse existieren, gibt es keinen Fall, in dem der oben genannte Zugriff tatsächlich erforderlich ist, und wenn ja, denke ich, dass ich einen Fehler im Design gemacht habe.
Der Grund, warum jeder wie die Öffentlichkeit darauf zugreifen kann, ist, dass es bereits auf der Theorie der Sexualität basiert. Ich frage mich, ob Python so süß ist, aber Sie denken wahrscheinlich, dass die Vorteile der Öffentlichkeit höher sind als die Vorteile der Privatheit. Ich bin mir nicht sicher, ob dies korrekt ist, aber in letzter Zeit beschränken sich die Fälle, in denen es privat gemacht wird (mit dem Attribut __start), hauptsächlich auf Folgendes.
sample9.py
>>> class Student(object):
... def __init__(self):
... self.__name = "Anonymous"
...
... def get_name(self):
... return self.__name
...
... class ChildStudent(Student):
... def __init__(self):
... super().__init__()
... self._name = "Child"
...
... c = ChildStudent()
... print(c.get_name(), c._name)
Anonymous Child
Dies bedeutet, dass das Definieren niemals schlecht oder ähnliches ist und Sie keine expliziten Getter oder Setter implementieren müssen.
sample10.py
>>> class OtherLangStyle(object):
... def __init__(self, val):
... self._val = val
...
... def get_val(self):
... return self._val
...
... def set_val(self, new_val):
... self._val = new_val
>>> ols = OtherLangStyle(1)
>>> ols.get_val()
1
>>> ols.set_val(2)
>>> ols.get_val()
2
>>> ols.set_val(ols.get_val() + 2)
>>> ols.get_val()
4
Nicht wie Python. Ich fühle mich wie es eingekapselt ist. .. .. Wie oben erwähnt, glaube ich nicht, dass es ein Problem gibt, wenn ich es einfach in der Öffentlichkeit implementiere, und ich implementiere es immer in der Öffentlichkeit.
sample11.py
>>> class PythonStyle(object):
... def __init__(self, val):
... self.val = val
... ps = PythonStyle(1)
... ps.val = 3
>>> ps.val
3
>>> ps.val += 4
>>> ps.val
7
Wenn Sie später einen Hook benötigen, hat Python eine super nützliche Sache namens "@ property" -Dekorator, und Sie können einfach "@ property", Setter, implementieren.
sample12.py
>>> class Student(object):
... def __init__(self, name, score):
... self._name = name
... self._score = score
...
... @property
... def score(self):
... return self._score
...
... @score.setter
... def score(self, score):
... before = self.score
... self._score = score
... self.notify_score_up(before)
...
... @property
... def name(self):
... return self._name
...
... def notify_score_up(self, before):
... print('%s score is up. %d to %d.' %
... (self.name, before, self.score))
...
... s = Student('nabetama', 0)
... s.score = 3
nabetama score is up. 0 to 3.
Wenn Sie den Setter so implementieren, können Sie auch den übergebenen Wert überprüfen!
Beim Schreiben von Python möchte jeder mindestens einmal einen Dekorateur schreiben. Wenn Sie die Bearbeitungszeit einer Funktion wissen möchten
sample13.py
>>> def checktime(func):
... @wraps(func)
... def wrapper(*args, **kwargs):
... import time
... start = time.time()
... res = func(*args, **kwargs)
... end = time.time() - start
... print('--------------------------------------------------')
... print(end)
... print('--------------------------------------------------')
... return res
... return wrapper
...
... @checktime
... def wait1():
... time.sleep(1)
... print('owata')
...
... wait1()
owata
... print(wait1)
<function wait1 at 0x1119a0d90> #wait1 und seine Metadaten werden zurückgegeben
--------------------------------------------------
1.003669023513794
--------------------------------------------------
Ich bereite einen Dekorateur wie diesen vor und mache so etwas wie eine Funktion zu verpacken. Der Grund für die Verwendung von functools.wraps
ist, dass der vom Dekorator zurückgegebene Wert (dh die Funktion) sich nicht selbst als aufrufende Methode interpretiert. Versuchen Sie, wraps () aus dem obigen Code zu entfernen.
sample14.py
>>> def checktime(func):
... def wrapper(*args, **kwargs):
... import time
... start = time.time()
... res = func(*args, **kwargs)
... end = time.time() - start
... print('--------------------------------------------------')
... print(end)
... print('--------------------------------------------------')
... return res
... return wrapper
...
... @checktime
... def wait1():
... time.sleep(1)
... print('owata')
...
... wait1()
... print(wait1)
owata
--------------------------------------------------
1.0004959106445312
--------------------------------------------------
<function checktime.<locals>.wrapper at 0x1118b5ae8> #...?
Sie können functools.wraps
verwenden, um die Metadaten der internen Funktion in die externe Funktion zu kopieren, selbst wenn sie in einen Dekorator eingeschlossen sind.
Python-Wörterbücher werden nicht sortiert. In realen Programmen gibt es jedoch Situationen, in denen Sie in der Reihenfolge sortieren möchten, in der die Schlüssel im Wörterbuch eingefügt werden. In einem solchen Fall ist collection.OrderedDict
praktisch.
sample15.py
>>> names = ['s', 'p', 'l', 'g']
>>> o = OrderedDict()
>>> for name in names:
... o[name] = 1
>>> o
OrderedDict([('s', 1), ('p', 1), ('l', 1), ('g', 1)])
>>> oo = dict()
>>> for name in names:
... oo[name] = 1
>>> oo
{'p': 1, 'l': 1, 'g': 1, 's': 1}
Wenn der Schlüssel nicht vorhanden ist, wird ein vorgegebener Standardwert zurückgegeben.
sample16.py
>>> from collections import defaultdict
>>> rec = defaultdict(int)
>>> rec['ore']
0
>>> rec
defaultdict(<class 'int'>, {'ore': 0})
In letzter Zeit schreibe ich gerne Dokumente mit Sphinx, aber in .git / hooks
sample.sh
#!/bin/sh
#
make html
Wenn Sie dies tun, bin ich froh, dass der HTML-Build jedes Mal automatisch ausgeführt wird.
Ich denke, es wird nicht viel, aber wenn ich das Python-Projekt, das ich dieses Jahr geschrieben habe, zurücklese, wird es herauskommen. Es wird mehr herauskommen und es ist der 12. gewesen, also werde ich einen Pinsel darauf legen. Es gibt viele andere Dinge, also schreibe ich es auf meinen eigenen Blog.
Ich habe es erwähnt, sobald ich darauf gekommen bin, aber ich werde mich 2016 verabschieden und denke, dass ich später über diesen Artikel nachdenken werde.
Recommended Posts