"Effective Python 2nd Edition" Chapitre 3 <Fonctions>

introduction

Environnement d'exécution

Lors de la publication de l'exemple de code, publiez le résultat de l'exécution dans l'environnement d'exécution suivant. Nous essaierons de le fournir sous une forme aussi exempte d'erreurs que possible, mais veuillez nous pardonner si cela ne fonctionne pas ou est faux.

Chapitre 3

Lancer une exception au lieu de Aucun

Que renvoyez-vous si quelque chose d'inattendu se produit lorsque vous le traitez dans une fonction? J'avais l'habitude de renvoyer «Aucun» jusqu'à ce que je sache cela. Par exemple, le code ci-dessous.

#Mauvais exemple (renvoyer None en cas d'inattendu)
from datetime import datetime
def parse_datetimes(datetime_string_list):
    result = []
    for datetime_string in datetime_string_list:
        try:
            result.append(datetime.strptime(datetime_string, "%Y-%m-%d"))
        except (ValueError, TypeError):
            return None
    return result

>>> print(parse_datetimes(["2020-09-22"]))
[datetime.datetime(2020, 9, 22, 0, 0)]
>>> print(parse_datetimes([]))
[]
>>> print(parse_datetimes(["hoge"]))
None

Cette fonction accepte une liste de chaînes représentant la date comme entrée, et renvoie une liste convertie en type datetime si l'analyse réussit, et "None" si elle échoue. À première vue, cela a l'air bien, mais cela pose deux problèmes.

Pour éviter ces problèmes, ** lancez une exception si quelque chose d'inattendu se produit dans la fonction **.

#Bon exemple (lancer une exception en cas d'inattendu)
from datetime import datetime
class MyError(Exception):
    def __init__(self, message):
        self.message = message

def parse_datetimes(datetime_string_list):
    result = []
    for datetime_string in datetime_string_list:
        try:
            result.append(datetime.strptime(datetime_string, "%Y-%m-%d"))
        except (ValueError, TypeError):
            raise MyError(f"La valeur saisie n'est pas valide: {datetime_string}")  #Lancer une exception
    return result

>>> print(parse_datetimes(["2020-09-22"]))
[datetime.datetime(2020, 9, 22, 0, 0)]
>>> print(parse_datetimes([]))
[]
>>> print(parse_datetimes(["hoge"]))
...
Traceback (most recent call last):
  ...
__main__.MyError:La valeur saisie n'est pas valide: hoge

S'il est implémenté pour lever une exception comme décrit ci-dessus, le traitement ne continuera pas tel quel à moins que l'exception «MyError» ne soit interceptée et que «None» et la liste vide «[]» soient identiques. C'est sûr car il n'y a aucune crainte de le manipuler.

Ne spécifiez pas une liste vide «[]» ou un dictionnaire vide «{}» comme argument par défaut

Si vous souhaitez utiliser une valeur pour l'argument, et sinon, utilisez la valeur par défaut. Dans ce cas, il est pratique de définir l'argument par défaut. Par exemple, le code ci-dessous.

#C'est un mauvais exemple
def square(value, result_list=[]):
    result_list.append(value ** 2)
    return result_list

Cette fonction ajoute le carré de «value» à «result_list» et le renvoie. Quant aux sentiments de ceux qui l'ont mis en œuvre,

Je pense que vous pensez.

# result_Si vous spécifiez list, le résultat sera renvoyé dans cette liste.
>>> result_list = [1, 4]
>>> result_list = square(3, result_list)
>>> print(result_list)
[1, 4, 9]

# result_Si list n'est pas spécifié, le résultat sera renvoyé dans la liste vide.
>>> result_list = square(3)
>>> print(result_list)
[9]

Il semble qu'il n'y ait aucun problème, non? Mais après cela, quelque chose d'étrange se produit.

>>> result_list = square(1)
>>> print(result_list)
[9, 1]  #cette?[1]Doit être retourné? ??
>>> result_list = square(2)
print(result_list)
[9, 1, 4]  #cette? Pourquoi y a-t-il 3 valeurs? ??

alors. Si vous ne le savez pas, vous vous retrouverez avec un comportement aussi mystérieux.

En fait, ** [les arguments par défaut ne sont évalués qu'une seule fois lorsque le module est chargé, pas à chaque fois que la fonction est appelée](https://docs.python.org/ja/3/ faq / programming.html # why-are-default-values-shared-between-objects) **. Par conséquent, si vous spécifiez une liste vide [] comme argument par défaut, la liste vide sera de plus en plus ajoutée ʻajouter`, ainsi le contenu de la liste augmentera chaque fois que vous l'appelez comme décrit ci-dessus. ..

C'est toujours bon si vous le savez et l'utilisez, mais ce n'est pas un comportement que tout le monde connaît, il est donc préférable d'éviter de spécifier une liste vide ou un dictionnaire vide comme argument par défaut. À la place, écrivez:

#Bon exemple
def square(value, result_list=None):
    if result_list is None:
        result_list = []  #En initialisant ici, il sera ajouté à la liste vide à chaque fois
    result_list.append(value ** 2)
    return result_list

S'il est implémenté comme ci-dessus, si result_list n'est pas spécifié, la liste vide sera retournée avec le résultat.

>>> result_list = square(3)
>>> print(result_list)
[9]
>>> result_list = square(1)
>>> print(result_list)
[1]
>>> result_list = square(2)
>>> print(result_list)
[4]

En passant, selon l'EDI, un avertissement peut être émis, alors assurez-vous de répondre si un avertissement est émis. PyCharm a émis l'avertissement suivant.

pycharm_warning

"Arguments de position uniquement" et "Arguments de mot-clé uniquement" ajoutés à partir de Python 3.8

Soudain, savez-vous ce que signifie le code ci-dessous?

def safe_division(numerator, denominator, /, hoge, *, ignore_overflow, ignore_zero_division):
    ...

Vous vous demandez peut-être, "Pourquoi est-ce que / ʻou * est écrit dans l'argument? " C'est ["Arguments de position seule (côté gauche de /) "et" Arguments de mot-clé seulement (côté droit de * `) ajoutés à partir de Python 3.8"](https://docs.python.org/ja/ Il est écrit en utilisant 3 / glossary.html # term-parameter).

Qu'est-ce que ça veut dire?

Je pense que les avantages de l'utilisation d'arguments de position uniquement et d'arguments de mots clés sont les suivants.

Écrire «/» ou «*» dans l'argument peut sembler étrange au début, mais comme mentionné ci-dessus, cela a aussi des mérites, il est donc préférable de l'utiliser au besoin. Cependant, cela ne fonctionnera pas s'il est inférieur à Python 3.8, alors faites attention!

Résumé

Sur la base du contenu du chapitre 3 de "Effective Python 2nd Edition", j'ai noté ce que j'ai appris et ce que j'ai pensé.

Les références

Site de référence

Recommended Posts

"Effective Python 2nd Edition" Chapitre 3 <Fonctions>
"Effective Python 2nd Edition" Chapitre 1 <Pythonic Thinking>
Fonctions Python
Livre de fourmis avec python (Chapter3 édition intermédiaire ~)
# Bases de Python (fonctions)
[Débutant] Fonctions Python
Fonctions Python faciles à utiliser
bases de python: fonctions
Guide du débutant Python (fonctions)
Cours de base Python (12 fonctions)
[Python of Hikari-] Chapitre 06-04 Fonctions (arguments et valeurs de retour 3)
Algorithme A * (édition Python)
Première 3e édition de Python
[Python] Mémo sur les fonctions
[Hikari-Python] Chapitre 06-01 Fonctions (fonctions intégrées et définitions de fonctions)
# 4 [python] Bases des fonctions
Fonction intégrée Python ~ Zip ~
[Python of Hikari-] Chapitre 06-03 Fonctions (arguments et valeurs de retour 2)
[Python] Chapitre 01-01 À propos de Python (First Python)
Fonctions intégrées Wrap Python
Élément de mémo Python efficace 3
[Hikari-Python] <Supplement> Chapitre 06-05 Fonctions (arguments et valeurs de retour 4)
Curry n'importe quelle fonction avec Python ...
Python> lambda> petites fonctions / fonctions de rappel
Introduction aux fonctions Python
Série Python 2 et série 3 (édition Anaconda)
Python pour l'analyse des données Chapitre 4
Construction de l'environnement CI ~ Édition Python ~
100 Language Processing Knock Chapitre 1 (Python)
Étude de Python Hour3: Fonctions
Installation de Python (édition Mac) (ancienne)
100 Language Processing Knock Chapitre 2 (Python)
Remplacer les fonctions de bibliothèque en Python
Python pour l'analyse des données Chapitre 2
Arguments de mots-clés pour les fonctions Python
Python #function 1 pour les super débutants
Paiza Python Primer 7: Comprendre les fonctions
Fonctions de tri et de comparaison Python 3
[Python] Chapitre 03-02 graphiques de tortues (comportement de la tortue)
Fonctions Python apprises avec la chimioinfomatique
Fonctions d'ordre supérieur et notation d'inclusion en Python
Python pour l'analyse des données Chapitre 3
Python Crawling & Scraping Chapitre 4 Résumé