Python study notes 6: the use of functions and modules, and the discussion of variable scope

1. Function usage

Today I learned Luo Hao’s blog post and summarized his relevant knowledge points, I hope it will be helpful to you.
GitHub original link

  • 求解: C M N = M ! N ! ( M − N ) ! , (M=7, N=3) C_M^N =\frac{M!}{N!(M-N)!}, \text{(M=7, N=3)} CMN=N!(MN)!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
finds the value = 35.0

1.1 The role of functions

  • For the above example, we used three for loops, which made the program repeated too many times. The programming master Mr. Martin Fowler once said: "Code has many bad smells, and repetition is the worst one!"
  • We need to create a letter to encapsulate these same functions into it

1.2 Define functions

  • Use the def keyword to define functions
  • After the function is executed, we can use the return keyword to return a value, which is equivalent to the dependent variable of the function in mathematics
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

Using the above function to define will make the program more concise and simple

1.3 Function parameters

  • The parameters of the function can have default values ​​and also support the use of variable parameters
  • The parameter setting is flexible, and there are many ways to use it
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 Function overloading (use the same function to complete different functions)

  • We set default values ​​for the parameters of the above two functions, which means that if the value of the corresponding parameter is not passed in when the function is called, the default value of the parameter will be used, so in the above code we The __add__ function can be called in a variety of different ways, which is consistent with the effect of function overloading in many other languages
  • In the above __add__ function, we have given the number of parameters, but if the number of parameters is unknown, what should we do?
    • You can add a * in front of the parameter to indicate that the parameter is 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. Use module management functions

  • For any programming language, naming identifiers such as variables and functions is a headache, because we will encounter the embarrassing situation of naming conflicts. The simplest scenario is to define two functions with the same name in the same .py file. Since Python does not have the concept of function overloading, the following definition will override the previous definition, which means that the two functions with the same name actually only have One exists
  • The simple understanding is that repeated function names will be overwritten by the latter
def sayHi():
    print("hello")
    return None
    
def sayHi():
    print('hello,world!')
    return None

sayHi()

hello,world!

2.1 Ways to solve the above problems

  • Create a file for each module, such as module1.py, module2.py...
  • All, in different files (modules), functions with the same name are allowed
  • When using, use the __import__ keyword to import the specified module
from module1 import sayHi

sayHi()

from module2 import sayHi

sayHi()


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

m1.sayHi()
m2.sayHi()
  • If the code is written like the following, then the last imported sayHi is called in the program, because the later imported sayHi overwrites the previously imported sayHi
from module1 import sayHi
from module2 import sayHi

sayHi()# 输出hello

from module2 import sayHi
from module1 import sayHi

sayHi()# 输出hello, world!

note:
  • If the module we import has executable code in addition to defining functions, then the Python interpreter will execute these codes when importing this module. In fact, we may not want this, so if we write the execution in the module Code, it is best to put these execution codes into the conditions shown below, so that unless the module is run directly, these codes under the if condition will not be executed, because only the directly executed module name is "__ 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__

Case 1: Realize the function of calculating the greatest common divisor and least common 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)

Case 2: Implement a function to judge whether a number is a palindrome number

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

isPal(1234321)


Case 3: Realize a function to judge whether a number is a prime number

def isPrime(num):
    # 判断一个数是不是素数
    for factor in range(2, num):
        if num % factor == 0:
            return False
    return True if num != 1 else False
note:
  • It can be seen from the above program that when we extract the repetitive and relatively independent functions in the code into functions, we can use these functions in combination to solve more complex problems, which is why we define and use functions A very important reason.

3. Issues about variable scope in Python

  • The order when looking for variables:
    • Local scope: c
    • Nested scope: b
    • Global scope: a
    • Built-in scope, such as some built-in identifiers, 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
hello
True
hello
35.0

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


if __name__ == '__main__':
    a = 100
    foo()
    print(a)         # 100
Through the above example, we know that the final output of a is still 100, because, according to the search order of python, when the local variable is found, it will no longer search for other variables.
3.1. If you want to use the value of a local variable in a global variable, you can use: global keyword
3.2. If you want the function inside the function to be able to modify the variable in the nested scope, you can use: nonlocal keyword
# 案例2:
def foo():
    global a
    a = 200
    print(a)  # 200


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

to sum up:

  • In actual development, we should minimize the use of global variables, because the scope and influence of global variables are too wide, and unexpected modifications and use may occur. In addition, global variables have longer than local variables The life cycle may cause the memory occupied by the object to be unable to be garbage collected for a long time .
  • In fact, reducing the use of global variables is also an important measure to reduce the degree of coupling between codes, and it is also a practice of Dimit's law .
  • Reduce the use of global variables means we should try to make the scope of variables in the function of the interior , but if we want a local variable life cycle extension, so that in the end it's the definition of a function call you can still use its value , This time you need to use closures .

Guess you like

Origin blog.csdn.net/amyniez/article/details/104415925