Tutoriel de base Python: fonction personnalisée

Polymorphisme

Nous pouvons voir que Python n'a pas besoin de prendre en compte le type de données d'entrée, mais le transmet à un code spécifique pour le juger et l'exécuter. La même fonction (comme la fonction d'addition ici my_sum()) peut être appliquée aux entiers, aux listes et aux caractères en même temps time. String et ainsi de suite.

Dans les langages de programmation, nous appelons ce polymorphisme de comportement. C'est aussi une grande différence entre Python et d'autres langages, tels que Java et C. Bien sûr, cette fonctionnalité pratique de Python apportera également de nombreux problèmes d'utilisation réelle. Par conséquent, si nécessaire, ajoutez une vérification du type de données au début.

def my_sum(a, b):
    if type(a) == type(b):
        if isinstance(a, (int, str, list)):
            return a + b
        else:
            raise Exception("input is not int/str/list")
    else:
        raise Exception("input type is not same")

print(my_sum(3, 5))
# 输出
# 8

print(my_sum([1, 2], [3, 4]))
# 输出
# [1, 2, 3, 4]

print(my_sum('hello ', 'world'))
# 输出
# hello world

print(my_sum([1, 2], 'hello'))
# 输出
# input type is not same

Imbrication des fonctions

Une autre caractéristique majeure des fonctions Python est que Python prend en charge l'imbrication des fonctions. La soi-disant imbrication de fonction signifie qu'il y a des fonctions à l'intérieur de la fonction, telles que:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def f1():
    print('hello')
    def f2():
        print('world')
    f2()
f1()

# 输出
hello
world

Avantages de la nidification

1. L'imbrication des fonctions peut garantir la confidentialité des fonctions internes.

Les fonctions internes ne peuvent être appelées et accessibles que par des fonctions externes, et ne seront pas exposées à la portée globale. Par conséquent, si vous avez des données privées (telles que l'utilisateur de la base de données, le mot de passe, etc.) dans votre fonction que vous ne voulez pas pour être exposé, alors vous pouvez utiliser L'imbrication de la fonction l'encapsule dans la fonction interne et n'est accessible que via la fonction externe. tel que:

def connect_DB():
    def get_DB_configuration():
        ...
        return host, username, password
    conn = connector.connect(get_DB_configuration())
    return conn

Voici la fonction get_DB_configurationest une fonction interne, elle ne peut pas connect_DB()être appelée autrement qu'une fonction distincte. En d'autres termes, les appels directs externes suivants sont erronés:

get_DB_configuration()

# 输出
NameError: name 'get_DB_configuration' is not defined

2. Une utilisation raisonnable de l'imbrication des fonctions peut améliorer l'efficacité opérationnelle du programme.

Regardez l'exemple suivant:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def factorial(input):
    # validation check
    if not isinstance(input, int):
        raise Exception('input must be an integer.')
    if input < 0:
        raise Exception('input must be greater or equal to 0' )

    def inner_factorial(input):
        if input <= 1:
            return 1
        return input * inner_factorial(input-1)
    return inner_factorial(input)

print(factorial(5))

Ici, nous utilisons une méthode récursive pour calculer la factorielle d'un nombre. Puisqu'il est nécessaire de vérifier si l'entrée est légale avant le calcul, elle est écrite sous forme d'imbrication de fonction, de sorte que si l'entrée est légale n'est vérifiée qu'une seule fois. Et si nous n'utilisons pas l'imbrication de fonction, elle sera vérifiée à chaque fois que la récursion est appelée, ce qui n'est pas nécessaire et réduira l'efficacité du programme.

Dans le travail réel, si vous rencontrez une situation similaire, la vérification des entrées n'est pas rapide et consommera une certaine quantité de ressources, il est donc nécessaire d'utiliser l'imbrication des fonctions.

Portée de la variable de fonction

1. Les variables locales ont une priorité plus élevée que les variables globales

Si vous rencontrez une situation où une variable locale et une variable globale à l'intérieur d'une fonction ont le même nom, alors à l'intérieur de la fonction, la variable locale couvrira la variable globale, comme ce qui suit:

MIN_VALUE = 1
MAX_VALUE = 10
def validation_check(value):
    MIN_VALUE = 3
    ...

IciMIN_VALUE=3

2. Vous ne pouvez pas modifier la valeur des variables globales à volonté dans la fonction

VALUE = 1
MAX_VALUE = 10
def validation_check(value):
    ...
    MIN_VALUE += 1
    ...
validation_check(5)

Si vous exécutez ce code, le programme signalera une erreur:

UnboundLocalError: local variable 'MIN_VALUE' referenced before assignment

En effet, l'interpréteur Python définit par défaut les variables à l'intérieur de la fonction en tant que variables locales, mais il constate également que la variable locale MIN_VALUE n'est pas déclarée, il ne peut donc pas effectuer d'opérations associées. Par conséquent, si nous devons changer la valeur des variables globales à l'intérieur de la fonction, nous devons ajouter la déclaration global:

MIN_VALUE = 1
MAX_VALUE = 10
def validation_check(value):
    global MIN_VALUE
    ...
    MIN_VALUE += 1
    ...
validation_check(5)

Le mot clé global ici ne signifie pas qu'une variable globale est recréée MIN_VALUE, mais il indique à l'interpréteur Python que la variable à l'intérieur de la fonction MIN_VALUEest la variable globale précédemment définie, pas une nouvelle variable globale, ni une variable locale. De cette manière, le programme peut accéder à la variable globale à l'intérieur de la fonction et modifier sa valeur.

3. Pour les fonctions imbriquées, la fonction interne peut accéder aux variables définies par la fonction externe, mais elle ne peut pas être modifiée. Si vous souhaitez la modifier, vous devez ajouter le mot clé nonlocal:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def outer():
    x = "local"
    def inner():
        nonlocal x # nonlocal关键字表示这里的x就是外部函数outer定义的变量x
        x = 'nonlocal'
        print("inner:", x)
    inner()
    print("outer:", x)
outer()
# 输出
inner: nonlocal
outer: nonlocal

Fermeture

La fermeture est similaire à la fonction imbriquée que nous venons de mentionner, la différence est:

  • Dans la fonction imbriquée, la fonction externe renvoie une valeur spécifique
  • La fonction externe dans la fermeture renvoie une fonction et la fonction retournée est généralement affectée à une variable, qui peut être exécutée plus tard.

Par exemple, si nous voulons calculer la n-ième puissance d'un nombre, nous pouvons écrire le code suivant avec une fermeture

def nth_power(exponent):
    def exponent_of(base):
        return base ** exponent
    return exponent_of # 返回值是exponent_of函数

square = nth_power(2) # 计算一个数的平方
cube = nth_power(3) # 计算一个数的立方 
square
# 输出
<function __main__.nth_power.<locals>.exponent(base)>

cube
# 输出
<function __main__.nth_power.<locals>.exponent(base)>

print(square(2))  # 计算2的平方
print(cube(2)) # 计算2的立方
# 输出
4 # 2^2
8 # 2^3

Notez que, dans l'implémentation de complet square = nth_power(2)et cube = nth_power(3)après l' nth_power()exposant de paramètre de fonction externe , la fonction interne sera toujours exponent_of()mémorisée. De cette façon, lorsque nous appelons square (2) ou cube (2) plus tard, le programme peut sortir le résultat en douceur sans signaler une erreur indiquant que l'exposant du paramètre n'est pas défini.

Les fermetures résolvent le problème des variables de base de l'opération de fonction, en particulier lorsque cette fonction doit être appelée plusieurs fois.

Supplément: UnboundLocalError

Bien que la fonction ne soit pas exécutée sans être appelée, l'interpréteur python effectuera une détection de variable ou une détection de type, par exemple s'il y a un rendement, s'il y en a, alors il sera marqué comme un générateur, qui est compilé en octets. le code est déjà déterminé.

import dis
x = 1
y = 2


def foo():
    print(x)
    x = 2
    print(y)

dis.dis(foo)

# 直接调用 foo() 会报错
# UnboundLocalError: local variable 'x' referenced before assignment

# 输出
  7           0 LOAD_GLOBAL              0 (print)
              2 LOAD_FAST                0 (x)
              4 CALL_FUNCTION            1
              6 POP_TOP

  8           8 LOAD_CONST               1 (2)
             10 STORE_FAST               0 (x)

  9          12 LOAD_GLOBAL              0 (print)
             14 LOAD_GLOBAL              1 (y)
             16 CALL_FUNCTION            1
             18 POP_TOP
             20 LOAD_CONST               0 (None)

Je suppose que tu aimes

Origine blog.csdn.net/qdPython/article/details/112787489
conseillé
Classement