Notes d'étude Python 6: l'utilisation des fonctions et des modules, et la discussion sur la portée des variables

1. Utilisation des fonctions

Aujourd'hui, j'ai appris le billet de blog de Luo Hao et j'ai résumé ses connaissances pertinentes, j'espère qu'il vous sera utile.
Lien d'origine GitHub

  • 求解 :CMN = M! N! (M - N)! , (M = 7, N = 3) C_M ^ N = \ frac {M!} {N! (MN)!}, \ Text {(M = 7, N = 3)}CMN=N ! ( M-N ) !M !,(M = 7, N = 3)
m = int(input('m = '))
n = int(input('n = '))
fm = 1
for num in range(1, m + 1):
    fm *= num
fn = 1
for num in range(1, n + 1):
    fn *= num
fmn = 1
for num in range(1, m - n + 1):
    fmn *= num
    
print("求得值为 = {}".format(fm/fn/fmn))

m = 7
n = 3
trouve la valeur = 35,0

1.1 Le rôle des fonctions

  • Pour l'exemple ci-dessus, nous avons utilisé trois boucles for, ce qui a fait répéter le programme trop de fois. Le maître de la programmation, M. Martin Fowler a dit un jour: "Le code a beaucoup de mauvaises odeurs, et la répétition est la pire!"
  • Nous devons créer une lettre pour y encapsuler ces mêmes fonctions

1.2 Définir les fonctions

  • Utilisez le mot-clé def pour définir des fonctions
  • Une fois la fonction exécutée, nous pouvons utiliser le mot-clé return pour renvoyer une valeur, qui est équivalente à la variable dépendante de la fonction en mathématiques
def factorial(num): # factorial:阶乘
    result = 1
    for n in range(1, num + 1):
        result *= n
    return result

m = int(input("m = "))
n = int(input("n = "))

print(factorial(m)/factorial(n)/factorial(m - n))

# 在Python的math模块中已经有一个factorial函数
# 就不需要自己定义函数了

import math

m = int(input("M = "))# 注意要将str强制转换为int
n = int(input("N = "))

c = math.factorial(m)/ \
    math.factorial(n)/ \
    math.factorial(m - n)
print(c)

m = 7
n = 3
35,0
M = 7
N = 3
35,0

L'utilisation de la fonction ci-dessus pour définir rendra le programme plus concis et simple

1.3 Paramètres de fonction

  • Les paramètres de la fonction peuvent avoir des valeurs par défaut et également prendre en charge l'utilisation de paramètres variables
  • Le paramétrage est flexible et il existe de nombreuses façons de l'utiliser
from random import randint

def rollDice(n = 2):
    """摇色子"""
    total = 0
    for i in range(n):
        total += randint(1, 6)
    return total

def add(a=0, b=0, c=0):
    """三个数相加"""
    return a + b + c

# 如果没有指定参数那么使用默认值摇两颗色子
print(rollDice()) # 4

# 摇三颗色子
print(rollDice(3)) # 14
print(add())       # 0
print(add(1))      # 1
print(add(1, 2))   # 3
print(add(1, 2, 3))# 6

# 传递参数时可以不按照设定的顺序进行传递
print(add(c=50, a=100, b=200))   # 350


1.4 Surcharge de fonction (utilisez la même fonction pour remplir différentes fonctions)

  • Nous définissons des valeurs par défaut pour les paramètres des deux fonctions ci-dessus, ce qui signifie que si la valeur du paramètre correspondant n'est pas transmise lorsque la fonction est appelée, la valeur par défaut du paramètre sera utilisée, donc dans le code ci-dessus we La fonction __add__ peut être appelée de différentes manières, ce qui est cohérent avec l'effet de la surcharge de fonction dans de nombreux autres langages
  • Dans la fonction __add__ ci-dessus, nous avons donné le nombre de paramètres, mais si le nombre de paramètres est inconnu, que devons-nous faire?
    • Vous pouvez ajouter un * devant le paramètre pour indiquer que le paramètre est variable
def add(*args):
    total = 0
    for i in args:
        total += i
    return total


# 在调用add函数时可以传入0个或多个参数
print(add())          	# 0
print(add(1))			# 1
print(add(1, 2))		# 3		
print(add(1, 2, 3))		# 6


2. Utiliser les fonctions de gestion des modules

  • Pour tout langage de programmation, nommer des identifiants tels que des variables et des fonctions est un casse-tête, car nous allons rencontrer la situation embarrassante des conflits de noms. Le scénario le plus simple consiste à définir deux fonctions avec le même nom dans le même fichier .py. Puisque Python n'a pas le concept de surcharge de fonction, la définition suivante remplacera la définition précédente, ce qui signifie que les deux fonctions avec le même nom en fait il n'y en a qu'un
  • La compréhension simple est que les noms de fonction répétés seront écrasés par ce dernier
def sayHi():
    print("hello")
    return None
    
def sayHi():
    print('hello,world!')
    return None

sayHi()

Bonjour le monde!

2.1 Façons de résoudre les problèmes ci-dessus

  • Créez un fichier pour chaque module, tel que module1.py, module2.py ...
  • Toutes, dans des fichiers (modules) différents, les fonctions portant le même nom sont autorisées
  • Lors de l'utilisation, utilisez le mot-clé __import__ pour importer le module spécifié
from module1 import sayHi

sayHi()

from module2 import sayHi

sayHi()


# 也可以使用下面的方法来区分使用了哪个 sayHi 函数
import module1 as m1
import module2 as m2

m1.sayHi()
m2.sayHi()
  • Si le code est écrit comme suit, alors le dernier sayHi importé est appelé dans le programme, car le sayHi importé plus tard écrase le sayHi précédemment importé
from module1 import sayHi
from module2 import sayHi

sayHi()# 输出hello

from module2 import sayHi
from module1 import sayHi

sayHi()# 输出hello, world!

Remarque:
  • Si le module que nous importons a du code exécutable en plus de définir des fonctions, alors l'interpréteur Python exécutera ces codes lors de l'importation de ce module. En fait, nous ne voulons peut-être pas cela, donc si nous écrivons l'exécution dans le module Code, c'est mieux pour mettre ces codes d'exécution dans les conditions indiquées ci-dessous, de sorte qu'à moins que le module ne soit exécuté directement, ces codes sous la condition if ne seront pas exécutés, car seul le nom du module directement exécuté est "__ main __"
module3.py:
def foo():
    pass


def bar():
    pass


# __name__是Python中一个隐含的变量它代表了: 模块的名字
# 只有被Python解释器直接执行的模块的名字才是: __main__
if __name__ == '__main__':
    print('call foo()')
    foo()
    print('call bar()')
    bar()

call foo ()
call bar ()

import module3

# 导入module3时, 不会执行模块中if条件成立时的代码 
# 因为模块的名字是module3而不是__main__

Cas 1: réaliser la fonction de calcul du plus grand diviseur commun et du plus petit commun multiple

def gcd(x, y):
    
    # 求最大公约数:两个或多个整数共有约数中最大的一个
    # (x, y) = (y, x) if x > y else (x, y)
    for factor in range(y, 0 , -1):
        if x % factor == 0 and y % factor == 0:
            return factor

        
def lcm(x, y):
    # 求最小公倍数
    return x * y // gcd(x, y)


gcd(200, 45)
lcm(7, 7)

Cas 2: implémenter une fonction pour juger si un nombre est un nombre palindrome

  • Par exemple: 1234321
def isPal(num):
    temp = num
    total = 0
    while temp > 0:
        total = total * 10 + temp % 10
        temp //= 10
    return total == num

isPal(1234321)


Cas 3: Réaliser une fonction pour juger si un nombre est un nombre premier

def isPrime(num):
    # 判断一个数是不是素数
    for factor in range(2, num):
        if num % factor == 0:
            return False
    return True if num != 1 else False
Remarque:
  • On peut voir à partir du programme ci-dessus que lorsque nous extrayons les fonctions répétitives et relativement indépendantes du code en fonctions, nous pouvons utiliser ces fonctions en combinaison pour résoudre des problèmes plus complexes, c'est pourquoi nous définissons et utilisons des fonctions Une raison très importante.

3. Problèmes concernant la portée des variables en Python

  • L'ordre lors de la recherche de variables:
    • Portée locale: c
    • Portée imbriquée: b
    • Portée mondiale: a
    • Portée intégrée, telle que certains identificateurs intégrés, input, print, int, etc.
def foo():
    b = 'hello'  # 局部变量,在foo函数的外部并不能访问到它
                 # 对于foo函数内部的bar函数来说,变量b属于嵌套作用域
                 # 在bar函数中,可以访问到它
    
    # Python中可以在函数内部再定义函数
    def bar():
        
        #nonlocal b
        #b = "nonlocal" # 修改嵌套变量的值
        
        c = True # 局部作用域,在bar函数之外是无法访问
        print(a)
        print(b)
        print(c)

    bar()
    print(b)  
    print(c)     # NameError: name 'c' is not defined

if __name__ == '__main__':
    a = 100      # 全局变量,属于全局作用域
    foo()
    # print(b)   # NameError: name 'b' is not defined

100
bonjour
Vrai
bonjour
35.0

# 案例1:
def foo():
    a = 200
    print(a)         # 200


if __name__ == '__main__':
    a = 100
    foo()
    print(a)         # 100
Grâce à l'exemple ci-dessus, nous savons que la sortie finale de a est toujours 100, car, selon l'ordre de recherche de python, lorsque la variable locale est trouvée, il ne cherchera plus d'autres variables.
3.1. Si vous souhaitez utiliser la valeur d'une variable locale dans une variable globale, vous pouvez utiliser: mot-clé global
3.2. Si vous souhaitez que la fonction à l'intérieur de la fonction puisse modifier la variable dans la portée imbriquée, vous pouvez utiliser: mot clé non local
# 案例2:
def foo():
    global a
    a = 200
    print(a)  # 200


if __name__ == '__main__':
    a = 100
    foo()
    print(a)  # 200
    

Pour résumer:

  • Dans le développement réel, nous devrions minimiser l'utilisation de variables globales, car la portée et l'influence des variables globales sont trop larges et des modifications et une utilisation inattendues peuvent se produire. En outre, les variables globales ont plus de temps que les variables locales Le cycle de vie peut provoquer la mémoire occupé par l'objet pour ne pas pouvoir être ramassé pendant une longue période .
  • En fait, réduire l'utilisation des variables globales est également une mesure importante pour réduire le degré de couplage entre les codes, et c'est aussi une pratique de la loi de Dimit .
  • Réduire l'utilisation de variables globales signifie que nous devrions essayer de rendre la portée des variables dans la fonction de l'intérieur , mais si nous voulons une extension de cycle de vie de variable locale, de sorte qu'à la fin, c'est la définition d'un appel de fonction que vous pouvez toujours utiliser sa valeur, cette fois, vous devez utiliser des fermetures .

Je suppose que tu aimes

Origine blog.csdn.net/amyniez/article/details/104415925
conseillé
Classement