>  기사  >  백엔드 개발  >  Python의 일반적인 기능에 대한 자세한 설명

Python의 일반적인 기능에 대한 자세한 설명

高洛峰
高洛峰원래의
2017-02-23 10:54:261081검색

1. 기능 소개

함수는 왜 있는 걸까요? 왜냐하면 코드를 작성할 때 기능이 없으면 반복되는 코드가 많아 코드 재사용률이 상대적으로 낮기 때문입니다. . . 그리고 이러한 코드는 유지 관리도 매우 어렵습니다. 이러한 문제를 해결하기 위해 자주 발생하는 일부 코드를 캡슐화하여 이 코드를 호출해야 할 때마다 호출할 수 있도록 하는 함수가 등장했습니다.

함수 정의: 함수는 이름(함수 이름)으로 캡슐화된 일련의 명령문을 의미합니다. 이 함수를 실행하려면 해당 함수 이름을 호출하면 됩니다.

특징:

코드 재사용
일관성 유지
확장성

2. Python에서 함수 생성

함수 정의 형식은 다음과 같습니다.

def 函数名(形参):
 函数体内部代码块

함수를 호출하려면 함수 이름(실제 매개변수)을 사용하여 함수를 호출하면 됩니다.

함수 이름의 명명 규칙은 변수의 명명 규칙과 동일합니다.

  • 함수 이름은 밑줄이나 문자로 시작해야 하며 문자의 조합을 포함할 수 있습니다. 숫자 또는 밑줄. 구두점은 사용할 수 없습니다.

  • 함수 이름은 대소문자를 구분합니다.

  • 함수 이름에는 예약어를 사용할 수 없습니다.

형식 매개변수와 실제 매개변수의 차이점:

함수 정의 시 매개변수는 함수 뒤에 괄호 안에 추가할 수 있습니다. 함수 이름에서 이러한 매개변수를 형식 매개변수라고 합니다. 형식 매개변수: 이름에서 알 수 있듯이 형식 매개변수이며 코드 이름일 뿐입니다.

실제 매개변수는 함수 호출 시 함수 이름 뒤에 괄호 안의 매개변수입니다. 형식 매개변수와 실제 매개변수는 1:1로 일치해야 합니다. 그렇지 않으면 함수 호출 시 오류가 발생합니다.

3. 함수 매개변수와 반환값

앞서 언급했듯이 함수의 형식 매개변수와 실제 매개변수는 일대일로 대응해야 하므로 매개변수 대응은 다음과 같습니다.

  1. 필수 매개변수

  2. 키워드 매개변수

  3. 기본 매개변수

  4. 가변 길이 매개변수 *args

  5. 가변 길이 매개변수 **kwargs

1. 🎜>

필수 매개변수는 함수 호출 시 전달되는 실제 매개변수와 함수 정의 시의 형식 매개변수와 일대일로 대응해야 하며, 그 이상은 대응 관계로 함수에 전달되어야 합니다. 적고 순서가 일관되어야 합니다.

예:

 def f(name,age):
   print(name,age)
 f("小明",18)

2. 키워드 매개변수

키워드 매개변수는 개념입니다. 실제 매개변수란 함수를 호출할 때 특정 매개변수가 특정 키워드에 속한다고 선언하는 것입니다. 키워드 인수를 사용하면 함수가 선언되었을 때와 다른 순서로 호출될 수 있습니다. Python 인터프리터가 인수 이름과 인수 값을 일치시킬 수 있기 때문입니다.

예:

 def f(name,age):
   print(name,age)
 f(name="小明",18)

3. 기본 매개변수

기본 매개변수는 함수 선언 시 매개변수의 기본값을 지정할 수 있습니다. 이러한 매개변수를 기본값 매개변수라고 합니다. 함수가 호출될 때 기본 매개변수가 해당 실제 매개변수를 수신하지 못하면 이 매개변수에 기본값이 할당됩니다.

예:

 def f(name,age,sex="male"):
   print(name,age,sex)
 f(name="小明",18)

이런 방식으로 기본 매개변수인 남성이 성별에 할당됩니다.

4. 무한 길이 매개변수 *args

파이썬에서 함수가 선언되면 (*변수 이름)을 사용하여 매개변수를 지정하여 불확실한 길이 매개변수를 허용할 수 있습니다. , 그러나 Python에서는 *args를 사용하여 가변 길이 매개변수를 허용하는 것이 관례입니다. 따라서 함수를 호출할 때 전달되는 매개변수는 가변 길이가 될 수 있습니다. args가 가변 길이 매개변수를 승인한 후 이러한 매개변수는 args에 액세스하여 얻을 수 있습니다.

예:

 def f(*args):
   print(args)
 f("小明",18,"male")

인쇄되는 것은 튜플이며, 이는 ("Xiao Ming", 18, "male") 다음을 저장합니다. 세 가지 요소.

5. 가변 길이 매개변수 **kwargs

그러나 위 args는 이름이 지정되지 않은 매개변수만 받을 수 있으며, 그러면 키워드 매개변수와 유사한 가변 길이 매개변수가 있는 경우 어떻게 해야 할까요? ? Python은 (**변수 이름)을 사용하여 가변 길이의 명명된 변수 매개변수를 받습니다. 마찬가지로 Python에서는 **kwargs를 사용하여 가변 길이 명명된 매개변수를 받는 것이 일반적입니다. kwargs는 가변 길이 매개변수를 수신한 후 이러한 매개변수를 사전에 저장하고 키를 통해 해당 매개변수 값을 얻을 수 있습니다.

예:

 def f(**kwargs):
   print(kwargs)
 f(name="小明",age=18,sex="male")

이러한 매개변수를 소개한 후 다음으로 소개할 것은 이러한 매개변수의 혼합 사용에 대한 것입니다. 상황:

함수가 위의 모든 유형의 매개변수를 사용하는 경우 어떻게 될까요? 모호함을 피하기 위해 Python에서는 여러 매개변수가 혼합된 경우 다음 순서 사용 규칙을 따르도록 규정합니다.

def f(필수 매개변수, 기본 매개변수, *args, **kwargs):

         pass
args와 kwargs가 동시에 존재하는 경우 args가 왼쪽에 있습니다

기본 매개변수는 필수 매개변수의 오른쪽, *args의 왼쪽에 있습니다

키워드 매개변수의 위치가 고정되어 있지 않습니다. ( ps: 함수 정의 시 키워드 매개변수가 결정되지 않습니다.)

那么,假如有一个列表想要传递进入一个不定长的未命名参数的函数中去,可以在该列表前面加上*实现,同理如果想传递一个字典进入不定长命名参数的函数中去,可以在该字典前面加上**

举个栗子:

 def f(*args,**kwargs):
   print(args)
   for i in kwargs:
     print("%s:%s"%(i,kwargs[i]))
 
 f(*[1,2,3],**{"a":1,"b":2})

函数的返回值

要想获取函数的执行结果,就可以用return语句把结果返回

注意:

函数在执行过程中只要遇到return语句,就会停止执行并返回结果,也可以理解为 return 语句代表着函数的结束 如果未在函数中指定return,那这个函数的返回值为None
return多个对象,解释器会把这多个对象组装成一个元组作为一个一个整体结果输出。

4.LEGB作用域

python中的作用域分4种情况:

L:local,局部作用域,即函数中定义的变量;

E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;

G:globa,全局变量,就是模块级别定义的变量;

B:built-in,系统固定模块里面的变量,比如int, bytearray等。 搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB。

local和enclosing是相对的,enclosing变量相对上层来说也是local。

在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)不会引入新的作用域。

变量的修改(错误修改,面试题里经常出):

 x=6
 def f2():
   print(x)
   x=5
 f2()
 
 # 错误的原因在于print(x)时,解释器会在局部作用域找,会找到x=5(函数已经加载到内存),但x使用在声明前了,所以报错:
 # local variable 'x' referenced before assignment.如何证明找到了x=5呢?简单:注释掉x=5,x=6
 # 报错为:name 'x' is not defined
 #同理
 x=6
 def f2():
   x+=1 #local variable 'x' referenced before assignment.
 f2()

global关键字

当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了,当修改的变量是在全局作用域(global作用域)上的,就要使用global先声明一下,代码如下:

 count = 10
 def outer():
   global count
   print(count) 
   count = 100
   print(count)
 outer()

nonlocal关键字

global关键字声明的变量必须在全局作用域上,不能嵌套作用域上,当要修改嵌套作用域(enclosing作用域,外层非全局作用域)中的变量怎么办呢,这时就需要nonlocal关键字了

 def outer():
   count = 10
   def inner():
     nonlocal count
     count = 20
     print(count)
   inner()
   print(count)
 outer()

小结

  • 变量查找顺序:LEGB,作用域局部>外层作用域>当前模块中的全局>python内置作用域;

  • 只有模块、类、及函数才能引入新作用域;

  • 对于一个变量,内部作用域先声明就会覆盖外部变量,不声明直接使用,就会使用外部作用域的变量;

  • 内部作用域要修改外部作用域变量的值时,全局变量要使用global关键字,嵌套作用域变量要使用nonlocal关键字。nonlocal是python3新增的关键字,有了这个 关键字,就能完美的实现闭包了。

5.特殊函数

递归函数定义:递归函数就是在函数内部调用自己

有时候解决某些问题的时候,逻辑比较复杂,这时候可以考虑使用递归,因为使用递归函数的话,逻辑比较清晰,可以解决一些比较复杂的问题。但是递归函数存在一个问题就是假如递归调用自己的次数比较多的话,将会使得计算速度变得很慢,而且在python中默认的递归调用深度是1000层,超过这个层数将会导致“爆栈”。。。所以,在可以不用递归的时候建议尽量不要使用递归。

举个栗子:

 def factorial(n): # 使用循环实现求和
   Sum=1
   for i in range(2,n+1):
     Sum*=i
   return Sum
 print(factorial(7))
 
 def recursive_factorial(n): # 使用递归实现求和
   return (2 if n==2 else n*recursive_factorial(n-1))
 
 print(recursive_factorial(7))
 
 def feibo(n): # 使用递归实现菲波那切数列
   if n==0 or n==1:return n
   else:return feibo(n-1)+feibo(n-2)
 print(feibo(8))
 
 def feibo2(n): # 使用循环实现菲波那切数列
   before,after=0,1
   for i in range(n):
     before,after=after,before+after
   return before
 print(feibo2(300))

递归函数的优点:定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

递归特性:

  • 必须有一个明确的结束条件

  • 每次进入更深一层递归时,问题规模相比上次递归都应有所减少

  • 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返 回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。)

6.函数式编程

关于函数式编程,我理解的也不是很深,但是python中有4个比较重要的内置函数,组合起来使用有时候能大大提高编程效率。

1 filter(function, sequence)

 str = ['a', 'b','c', 'd']
 def fun1(s):
   if s != 'a':
     return s
 ret = filter(fun1, str)
print(list(ret))# ret是一个迭代器对象

对sequence中的item依次执行function(item),将执行结果为True的item做成一个filter object的迭代器返回。可以看作是过滤函数。

2 map(function, sequence)

 str = [1, 2,'a', 'b']
 def fun2(s):
   return s + "alvin"
 ret = map(fun2, str)
 print(ret)   # map object的迭代器
 print(list(ret))# ['aalvin', 'balvin', 'calvin', 'dalvin']

对sequence中的item依次执行function(item),将执行结果组成一个map object迭代器返回. map也支持多个sequence,这就要求function也支持相应数量的参数输入:

 def add(x,y):
   return x+y
 print (list(map(add, range(10), range(10))))##[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

3 reduce(function, sequence, starting_value)

 from functools import reduce
 def add1(x,y):
   return x + y
 
 print (reduce(add1, range(1, 101)))## 4950 (注:1+2+...+99)
 print (reduce(add1, range(1, 101), 20))## 4970 (注:1+2+...+99+20)

对sequence中的item顺序迭代调用function,如果有starting_value,还可以作为初始值调用.

4 lambda

普通函数与匿名函数的对比:

 #普通函数
 def add(a,b):
   return a + b
 
 print add(2,3)
 
 #匿名函数
 add = lambda a,b : a + b
 print add(2,3)

 #========输出===========
 5
 5

匿名函数的命名规则,用lamdba 关键字标识,冒号(:)左侧表示函数接收的参数(a,b) ,冒号(:)右侧表示函数的返回值(a+b)。

因为lamdba在创建时不需要命名,所以,叫匿名函数

更多python常用函数详解相关文章请关注PHP中文网!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.