Modèles Python qui ont été publiés dans le monde et ont été examinés plus tard

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.

Libérer la priorité absolue

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!

Ne jetez pas de \ _ \ _ données \ _ \ _ lors de la création d'un objet

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']
        ...

ne pas utiliser else après la boucle for, while

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!')

N'écrivez pas comme si les arguments par défaut étaient définis dynamiquement

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.

Choisissez public plutôt que privé

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

Ne définissez pas les méthodes get ou set

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 pour cet attribut

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!

Utilisez functools.wraps lors de la création de décorateurs

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.

Utilisez des algorithmes et des structures de données intégrés

Trier le dictionnaire

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}

Dictionnaire par défaut

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})

prime

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.

Résumé

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.

Recommended Posts

Modèles Python qui ont été publiés dans le monde et ont été examinés plus tard
Dites bonjour au monde avec Python avec IntelliJ
Exemples PHP et Python qui ont atteint l'API ChatWork
J'ai senti que j'avais porté le code Python en C ++ 98.
L'attitude que les programmeurs devraient avoir (Le Zen de Python)
[C / C ++] Passez la valeur calculée en C / C ++ à une fonction python pour exécuter le processus et utilisez cette valeur en C / C ++.
Commande de raccourci Jedi-vim qui vous permet de faire référence à la source de la définition et à la destination de la définition en Python
Une histoire qui facilite l'estimation de la surface habitable à l'aide d'Elasticsearch et de Python
[Python] Un programme pour trouver le nombre de pommes et d'oranges qui peuvent être récoltées
Créer un environnement Python et transférer des données vers le serveur
Je veux connaître la nature de Python et pip
J'ai essayé d'énumérer les différences entre java et python
Comment écrire une classe méta qui prend en charge à la fois python2 et python3
Nous avons publié une extension qui vous permet de définir des données xarray comme une classe de données Python.
Déterminez le format de la date et de l'heure avec Python et convertissez-le en Unixtime
L'histoire selon laquelle la version de python 3.7.7 n'était pas adaptée à Heroku
Comment réussir et étudier l'examen de base de la certification d'ingénieur Python 3
Expressions régulières faciles et solides à apprendre en Python
Comment obtenir des abonnés et des abonnés de Python à l'aide de l'API Mastodon
[Introduction à Python] J'ai comparé les conventions de nommage de C # et Python.
[Python] Comment obtenir le premier et le dernier jour du mois
Comment déterminer qu'une clé croisée a été entrée dans Python3
Utilisez python sur Raspberry Pi 3 pour éclairer la LED (Hello World)
Ecrire un programme qui abuse du programme et envoie 100 e-mails
À propos du bogue qu'Anaconda ne parvient pas à importer numpy et scipy
Un script qui renvoie 0, 1 attaché au premier Python prime
La route pour installer Python et Flask sur un PC hors ligne
Un guide rapide de PyFlink qui combine Apache Flink et Python
Convertissez le résultat de python optparse en dict et utilisez-le
Vérification de la théorie selon laquelle "Python et Swift sont assez similaires"
Assurez-vous que python peut convertir / convertir une chaîne de caractères en int
Essayer d'implémenter et de comprendre les arborescences de segments étape par étape (python)
[Introduction à Python] Comment utiliser l'opérateur booléen (et ・ ou ・ non)
[python] Une note que j'ai commencé à comprendre le comportement de matplotlib.pyplot
[Python] Un programme qui fait pivoter le contenu de la liste vers la gauche
Comment afficher les octets de la même manière en Java et Python