Bonjour. Je suis Nabeta, qui est ingénieur logiciel dans le groupe d'infrastructure. C'est la nuit du 11 (22h00), donc j'écris cet article à la hâte. Je continuerai à écrire après l'avoir trouvé jusqu'à la dernière minute. Frappez le clavier aussi calmement que vous n'avez pas le temps, Luke.
En gros, la sortie n'attend pas sauf quand elle est assez dangereuse, donc je pense que tout le monde a de l'expérience dans le cas de l'envoyer dans le monde en tant que "Non!". De plus, je n'ai pas pu prendre le temps de refactoriser le code existant, et j'ai écrit un code étrange à cause de mon manque de capacité. Après cela, je réfléchirai à certains des modèles que j'ai corrigés. Quoi qu'il en soit, je n'ai pas le temps, alors faisons de notre mieux pour remplir l'espace pour les articles!
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 est un dictionnaire. Même si l'intérieur de ʻinit_data
qui est mangé par ʻApi est changé, je n'ai pas à changer l'implémentation de ʻApi
, et je l'ai souvent utilisé en pensant que c'était une métaprogrammation et cool. Si vous le lisez, vous devez connaître l'implémentation interne de ʻinit_data, et d'autres classes et méthodes qui implémentent en utilisant l'objet ʻApi
, ce qui est assez pénible. Si vous générez ʻinit_data` dans le code, ce sera vraiment désagréable à lire.
C'était plus facile à lire plus tard si je préparais un dictionnaire qui définissait toutes les clés et valeurs, ou créais une classe qui les encapsulait.
sample2.py
class Api(object):
def __init__(self, init_data):
self.name = name
self.a = init_data['a']
self.b = init_data['b']
...
Python vous permet de mettre ʻelse` après un bloc de boucles.
sample3.py
for i in range(5):
print('Count %d' % i)
else:
print('ELSE BLOCK!!')
Ceci est exécuté immédiatement après la fin de la boucle. Il n'y a aucun sentiment d '«autre». De plus, celui-ci est ignoré lorsque break
est fait, donc je ne comprends plus la signification de ʻelse`.
sample4.py
>>> for i in range(5):
... if i == 3:
... break
... print(i)
... else:
... print('ELSE!') # unreachable!
0
1
2
Ensuite, je me demandais à quoi servait ce type, mais je pense que ce serait un peu efficace pour traiter quelque chose qui remplit les conditions en boucle. Cependant, dans ce cas, il est plus facile à lire si vous créez une fonction à cet effet. Le nom ʻelse` est trompeur et ne doit pas être utilisé.
Vous trouverez ci-dessous celui qui scanne et renvoie le résultat si vous avez trouvé ou non ce que vous recherchiez.
sample5.py
#C'est mieux
def power_up_if(users):
found = False
for user in users:
if user == 42: #Revenez dès que la condition que vous recherchez est trouvée
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!')
Vous voudrez rarement utiliser des arguments de mots clés non statiques comme valeurs par défaut pour les fonctions et les méthodes.
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!!
Je pense que c'est une spécification que vous saurez sûrement (pas à pas) si vous écrivez Python tel quel. L'argument par défaut n'est évalué qu'une seule fois lorsque la fonction est définie. Cela signifie que la valeur de l'argument par défaut sera déterminée lors du chargement du module et ne sera plus jamais évaluée. J'ai également marché sur cette spécification et payé beaucoup d'argent pour résoudre le problème. Comme solution de contournement
sample7.py
>>> def log_out(msg, when=None):
... """Journal de sortie avec horodatage
...
... Args:
... msg:Message du journal
... when:Date et heure de la sortie du journal. Sinon, réglez la date et l'heure actuelles.
... """
... 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
Je pense qu'il est préférable de définir la valeur de l'argument par défaut sur «Aucun» et de le déterminer par l'idiome de «when = datetime.datetime.now () if when is None else when» dans la fonction. S'il y en a, je le définirai, et sinon, je le ferai ici.
Autant que je sache, il n'y a pas de privé absolu en Python.
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}
Par conséquent, toute personne connaissant les règles de conversion du compilateur comme décrit ci-dessus peut accéder aux attributs privés. Cependant, puisque privé et public existent en tant que visibilité de la classe, il n'y a aucun cas où l'accès ci-dessus est réellement requis, et si c'est le cas, je pense que j'ai fait une erreur dans la conception.
Ensuite, la raison pour laquelle tout le monde peut accéder au public comme c'est qu'il est déjà basé sur la théorie de la sexualité. Je me demande si c'est ce que Python est si mignon, mais vous pensez probablement que les avantages d'être public sont plus élevés que les avantages d'être privé. Je ne suis pas sûr que ce soit correct, mais ces derniers temps, les cas de rendre privé (en donnant l'attribut __start) sont principalement limités aux suivants.
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
Ce n'est en aucun cas un mal ou quelque chose comme ça, et vous n'avez pas à implémenter explicitement des getters ou des setters.
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
Pas comme Python. J'ai l'impression que c'est encapsulé. .. .. Comme mentionné ci-dessus, je ne pense pas qu'il y ait de problème si je le mets simplement en œuvre en public, et je le mets toujours en œuvre en public.
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
Si vous avez besoin d'un hook plus tard, Python a une chose super utile appelée un décorateur @ property
, et vous pouvez simplement implémenter @ property
, setter.
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.
En implémentant le setter comme ceci, vous pouvez également vérifier la valeur passée!
Lors de l'écriture de Python, tout le monde veut écrire un décorateur au moins une fois. Lorsque vous souhaitez connaître le temps de traitement d'une fonction
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 et ses métadonnées sont renvoyées
--------------------------------------------------
1.003669023513794
--------------------------------------------------
Je prépare un décorateur comme celui-ci et je fais quelque chose comme emballer une fonction. La raison d'utiliser functools.wraps
est que la valeur (c'est-à-dire la fonction) renvoyée par le décorateur ne s'interprète pas comme la méthode appelante. Essayez de supprimer wraps () du code ci-dessus.
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> #...?
Vous pouvez utiliser functools.wraps
pour copier les métadonnées de la fonction interne dans la fonction externe même si elle est enveloppée dans un décorateur.
Les dictionnaires Python ne sont pas triés. Cependant, dans les programmes réels, il y a des moments où vous souhaitez trier dans l'ordre dans lequel les clés du dictionnaire sont insérées. Dans un tel cas, «collection.OrderedDict» est pratique.
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}
Si la clé n'existe pas, elle renverra une valeur par défaut prédéterminée.
sample16.py
>>> from collections import defaultdict
>>> rec = defaultdict(int)
>>> rec['ore']
0
>>> rec
defaultdict(<class 'int'>, {'ore': 0})
Récemment, j'aime écrire des documents avec Sphinx, mais en .git / hooks
sample.sh
#!/bin/sh
#
make html
Si vous le faites, je suis heureux que la construction html s'exécute automatiquement à chaque fois.
Je pense que ce ne sera pas beaucoup, mais si je relis le projet Python que j'ai écrit cette année, il sortira. Il sortira plus, et il a été 12e, alors je vais mettre un pinceau dessus. Il y a beaucoup d'autres choses, je vais donc l'écrire sur mon propre blog.
Je l'ai mentionné dès que je l'ai trouvé, mais je vais dire au revoir en 2016, pensant que je réfléchirai à cet article plus tard.