>  기사  >  백엔드 개발  >  Python 배우기 3장__함수형 프로그래밍, 재귀, 내장 함수

Python 배우기 3장__함수형 프로그래밍, 재귀, 내장 함수

高洛峰
高洛峰원래의
2017-02-22 10:24:321913검색

1. 함수형 프로그래밍

함수 만들기

함수형 프로그래밍은 def 키워드, 함수 이름, 대괄호와 콜론, 대괄호 안의 매개변수로 구성됩니다. 함수 함수 이름과 괄호만 쓰면 됩니다

형식: def function (parameter) 다음으로 함수를 만듭니다

#!/usr/bin/env python
# -*- coding:utf-8 -*-

#创建函数
def print_str():
    print("Hello World")

#调用函数
print_str()


첫 번째 함수

변수의 범위

다음 코드에서 먼저 변수 a를 설정하는 예를 살펴보겠습니다. ="haha " 그런 다음 함수에 a = "heihei"를 넣고 마지막으로 함수를 실행하여 변수 a의 결과를 출력합니다

a가 "heihei"와 같지 않지만 "haha"가 왜 나타나는지 알아냈습니다. 우리는 이전에 할당한 이 현상의 비밀을 즉시 밝힙니다

rree


가변 범위 예시 1

전역 변수 지역 변수 포함

변수의 범위는 변수가 적용되는 범위임이 분명하며, 이 범위를 벗어나면 사용할 수 없습니다

전역 변수: 일반적으로 전역 변수는 스크립트가 끝난 후에도 유지되며 모든 함수가 이에 액세스할 수 있습니다.

지역 변수: 지역 변수가 있는 함수 내에서만 호출할 수 있습니다. 전역변수로 선언되어 다른 함수를 호출할 수 없으며, 지역변수

함수가 실행되면 더 이상 존재하지 않게 된다

#!/usr/bin/env python
# -*- coding:utf-8 -*-


a = "haha"

#创建函数
def print_str():
    a = "heihei"
    print("Hello World")

#调用函数
print_str()
print("我是变量a:",a)


전역변수와 지역변수

global

Global은 선언된 지역변수 이름이 같으면 지역변수를 전역변수로 바꿀 수 있다. 전역 변수 이름으로 지역 변수가 전역 변수를 덮어씁니다.

전역 변수를 사용하여 변수를 선언하려면 변수보다 먼저 선언해야 합니다. 그렇지 않으면 Python에서

오류 메시지: SyntaxWarning: 전역 선언 앞에 'a'가 할당되었습니다. 전역 a

#!/usr/bin/env python
# -*- coding:utf-8 -*-


a = "haha"

#创建函数
def print_str():
    a = "heihei"
    print("我是局部变量a:",a)


#调用函数
print_str()
print("我是全局变量a:",a)


gloable

2. 참여 반환값 전달

매개변수 전달

함수는 상대적으로 사용법이 간단하고 이해하기 쉽지만, 매개변수는 더 많이 변경됩니다. 매개변수는 문자열, 숫자, 사전 및 목록을 받을 수 있습니다.

그리고 호출할 때 어떤 매개변수에 어떤 값을 할당할지 지정할 수도 있습니다.

#!/usr/bin/env python
# -*- coding:utf-8 -*-

a = "haha"

#创建函数
def print_str():
    global a
    a = "heihei"
    print("我是局部变量a:",a)

#调用函数
print_str()
print("我是全局变量a:",a)


매개변수 전달

목록이나 사전을 전달하고 싶을 때는 어떻게 해야 하나요?

#!/usr/bin/env python
# -*- coding:utf-8 -*-

#创建函数
def print_str(Name,Age,Aender):
    print('''
    Name:%s
    Age:%s
    Aender:%s
    '''%(Name,Age,Aender))

#用户输入
in_name = input("请输入你的名字:")
in_age = input("请输入你的年龄:")
in_aender = input("请输入你的性别:")

#固定位置传参
print_str(in_name,in_age,in_aender)
print("----------------------------------")

#不固定位置传参
print_str(in_name,Aender=in_aender,Age=in_age)


사전 또는 목록으로 전달

기본 매개변수

함수에서 기본 매개변수를 설정할 수도 있습니다. 기본 매개변수는 이 매개변수에 값을 전달할 수도 있고 값을 전달하지 않을 수도 있음을 의미합니다. 이 매개변수는 기본값

#!/usr/bin/env python
# -*- coding:utf-8 -*-

def print_str(lists):
    if type(lists) == list:
        print('''
        Name:%s
        Age:%s
        Aender:%s
        '''%(lists[0],lists[1],lists[2]))
    else:
        print('''
        Name:%s
        Age:%s
        Aender:%s
        '''%(lists["name"],lists["age"],lists["aenber"]))

#传入列表
userlist = ["Ben","22","Man"]
print_str(userlist)

print("----------------------------------")
#传入字典
userdict = {"name":"Ben","age":"022","aender":"Man"}
print_str(userlist)


기본 매개변수

고정되지 않은 매개변수

고정되지 않은 매개변수의 의미는 이 함수는 사용자가 몇 개의 값을 전달하고 싶은지 확실하지 않을 때 사용됩니다. 물론 고정되지 않은 매개변수만으로 함수를 호출할 때는 매개변수를 전달할 수 없습니다.

고정되지 않은 매개변수는 하나의 *와 두 개의 *로 나뉩니다. *args는 들어오는 매개변수를 기본 형식으로 변환하고 **kwargs는 들어오는 매개변수를 사전으로 변환합니다. 물론 *ages는 다른 이름일 수 있습니다. 하지만 사양에서는 *args를 사용하고 **kwargs

#!/usr/bin/env python
# -*- coding:utf-8 -*-

def print_str(lists,Country="China"):
    if type(lists) == list:
        print('''
        Name:%s
        Age:%s
        Aender:%s
        country:%s
        '''%(lists[0],lists[1],lists[2],Country))
    else:
        print('''
        Name:%s
        Age:%s
        Aender:%s
        country:%s
        '''%(lists["name"],lists["age"],lists["aenber"],Country))

#传入列表
userlist = ["Ben","22","Man"]
print_str(userlist)

print("----------------------------------")
#传入字典
userdict = {"name":"Ben","age":"022","aender":"Man"}
print_str(userlist,"America")


고정되지 않은 매개변수
형식 매개변수는 *와 **를 취할 수 있으므로 실제 매개변수도 *와 **를 취할 수 있으며, *는 목록과 함께 사용되고 **는 사전과 함께 사용됩니다! " Ben","22","Man"은 함수에 하나씩 전달되고 **는 사전을 name="Ben",age="022",gender="Man"

이 키-값 쌍은 함수에 전달됩니다.

 

형식 매개변수
형식 매개변수:

변수는 호출될 때만 메모리 단위를 할당받고, 호출이 종료되면 할당된 메모리가 즉시 해제됩니다. 단위. 따라서 형식 매개변수는 함수 내에서만 유효합니다. 함수 호출 종료 후 메인 호출로 복귀 함수 종료 후 형식 매개변수 변수는 더 이상 사용할 수 없음

실제 매개변수 :

상수일 수 있음 , 변수, 표현식, 함수 등 실제 매개변수가 어떤 양의 유형이든지 관계없이 함수 호출 시에는 이러한 값이 형식 매개변수로 전달될 수 있도록 명확한 값이 있어야 합니다. 따라서

매개변수에 대한 특정 값을 얻으려면 사전에 할당, 입력 및 기타 방법을 사용해야 합니다

  简学Python第三章__函数式编程、递归、内置函数

  注!当普通参数和默认参数和非固定参数结合使用的时候,要遵循一个顺序,普通参数在默认参数前面,默认参数在非固定参数前面

  

  返回值

  在正常使用函数的时候,函数是可以把函数内部处理的结果返回给函数调用者的,在没有返回值得函数中会保留None传给函数调用者,返回值可以返回序列等

  在函数执行的时候遇到return函数会停止执行,并返回结果

#!/usr/bin/env python
# -*- coding:utf-8 -*-

#创建函数
def print_str(Age):
    if int(Age) <= 30:
        return "你才%s啊!真年轻"%(Age)
    else:
        return "你都%s啦!老家伙"%(Age)

in_age = input("请输入你的年龄:")
word = print_str(in_age)
print(word)

return  

  嵌套函数

  在函数内部也可以写函数,这样就是外层函数套着内侧函数,这种形式称之为嵌套函数,同理因为作用域的关系嵌套函数只能内部调用

  return unction_2(stra)+"我是第二层\n" 就等于先 c = unction_2(stra) 然后 return c+"我是第二层\n"

def unction(stra):
    def unction_2(stra_2):
        return stra_2+"我是第三层\n"
    return unction_2(stra)+"我是第二层\n"

r_str = unction("")
print(r_str+"我是第一层")


嵌套函数 

三、递归

  前面已经介绍了函数相关的知识,在函数中,函数可以调用其他的函数,并且函数还可以调用自身,利用这种特性我们可以完成一些特定的

  操作,这种函数调用自身的形式就是递归

  def recursion() :
    return recursion()

  在递归中不能像上面两行一样一直调用自身,这样一会程序就会崩溃,因为它永远的在调用就跟while死循环一样出不去,所以递归也需要进

  判断给它出口

  例子:阶乘

  什么是阶乘,阶乘就是给一个自然数N,然后计算N的阶乘那么 N = 1x2x3x4....N ,这个就是阶乘,我们可以把它到过来看,

  N = N x (n-1) x (n-2) x (n-3) ...... 1 一直乘到括号中的值等于1,既然知道了阶乘是什么,那么我们来写一个程序实现它

 def factorial(n):
     for i in range(1,n):
         n *= i
     return n
 c = factorial(4)
 print(c)

阶乘非递归版本

  剖析:上面的例子首先把n=4传入进去,然后通过 for i in range(1,4)让i分别等于1,2,3,然后进行 n*=i,我们可以看出这个for循环是循环3次的

  第一次(n = n*i) n = 4*1 ,此时n还是等于4

  第二次(n = 4*i)  n = 4*2 此时n = 8 

  第三次(n = 8*i)  n = 8*3 此时n等于24

  此时for循环了3次所以结束了,通过return把n的结果返回,所以最终结果算出 4的阶乘等于24

  递归版本

  下面看递归版本的阶乘

def factorial(n) :
    if n == 1:
        return 1
    else:
        return n * factorial(n-1)
c = factorial(4)
print(c)

阶乘递归版本

  剖析:

  首先c = factorial(4)开始执行函数,然后进行第一次判断 n == 1,显然第一层n不等于1,然后碰到return n * factorial(n-1),碰到return本来是要返回的,但是 factorial(n-1)

  有调用了factiorial这个函数,因此进入了第二层

  第二层因为上一层传入的参数是n-1,所以第二层的n是等于3的,然后判断,这一层的n也不等于1,然后又进入第三层

  第三层n等于3,然后判断这一层的n还不等于1,然后又进入第四层

  简学Python第三章__函数式编程、递归、内置函数

  到第四层的时候这时的 n就等于1,所以触发了 return 1 不再调用函数了,所以就开始返回

  返回第三层 return n * factorial(n-1) , 此时factorial(n-1) 就等于第四层return上去的1,所以第三层返回时就等于return n * 1(return 2 * 1),并且第三层n是等于2的

  返回第二层factorial(n-1)就等于第三层return上去的2,并且第二层n是等于3的,return 3 * 2

  返回第一层factorial(n-1)就等于第二层return上去的6,并且第一层n是等于4的,return 4 * 6

  到此为止递归执行完毕,c就等于 4 * 6 c=24

   简学Python第三章__函数式编程、递归、内置函数

   

四、匿名函数

  匿名函数也叫lambda函数,函数没有具体的名称。语法:function name=  lambda  args(多个参数用逗号隔开): Expression(表达式,表达式的结果就是返回值)

  先来看一个最简单例子:

#普通函数
def func(arg1,arg2):
    return arg1-arg2

#lambda函数
func_2 = lambda arg1,arg2: arg1-arg2

#传参执行
print(func(5,4))
print(func_2(5,4))

匿名函数

  有认识,这个匿名函数和普通函数没有什么区别么,其实匿名函数就像三元运算一样,并且能够用lambda函数有几大优势

  1、在一些不会再别的地方调用的函数,我们可以使用匿名函数,并且这样简化了代码,看起来更加整洁。

  2、lambda函数将会搭配一些内置函数来使用(下面会涉及到)

 

五、闭包

  在上面的示例中知道了函数可以调用函数本身,这种形式称之为递归,那么还可以将函数作为参数返回,这种形式就称之为闭包

  闭包最大的好处就是即用即调,闭包对于安装计算,隐藏状态,以及在函数对象和作用域中随意地切换是很有用的!

#!/usr/bin/env python
# -*- coding:utf-8 -*-
def func(rate):
    count = [0]
    def add_func(arg):
        count[0] +=1
        print("第%s次调用"%count[0])
        arg = arg - arg*rate
        return arg
    return add_func

closure = func(0.03)
print(closure(1000))
print(closure(1100))
print(closure(1200))

闭包示例

  例子中做了一个减去手续费后返回余额的功能,首先执行了func函数,将利率封装了进去,然后,func函数把它内部的函数进行了进行了返回

  要知道当函数不加括号的时候是不执行的!,所以此时closoure就是 add_func 函数的内存地址,当想要使用这个功能的时候,直接把closoure加括号

  并传入值即可执行。并且可以看到的是在全局作用域中执行,随时可以切换到局部作用域。

 

六、高阶函数

  函数可以用来当做返回值,可以用调用自己本身,高阶函数就是函数的参数把另一个函数作为参数,这种函数就称之为高阶函数。

def func_1(num):
    return num+1

def func_2(num):
    return num-1

def func_main(num,func):
    #  可以简写成return func(num)
    results = func(num)
    return results

results = func_main(10,func_1)
print(results)
print(func_main(10,func_2))

高阶函数

  编写高阶函数,就是让函数的参数能够接收别的函数。

  

七、内置函数

  内置函数就是python中内置的一些方法

  

  内置函数使用方法示例,详细介绍请参考

# !/usr/bin/env python
# -*- coding:utf-8 -*-

#返回数字的绝对值。 参数可以是整数或浮点数。 如果参数是复数,则返回其大小。
print(abs(-1.11))

#传入一个可被循环的元素,如果这个元素中有一个为False则都为假
# 0 空值 False 都为假
print(all([1,2,3]))

#与all相反,只有一个为真,则为真;
print(any([0,2,False]))

#这个函数跟repr()函数一样,返回一个可打印的对象字符串方式表示。当遇到非ASCII码时
#就会输出\x,\u或\U等字符来表示。与Python 2版本里的repr()是等效的函数。
print(ascii("dsads"),ascii(66),ascii(&#39;b\23&#39;))

#将十进制转换为二进制;
print(bin(10))

#返回布尔值,即True或False之一,如果参数为false或省略,则返回False; 否则返回True。
print(bool(1))

#根据传入的参数创建一个新的字节数组
#如果传入字符串必须给出编码
print(bytearray(&#39;你好&#39;,&#39;utf-8&#39;))
#当source参数是一个可迭代对象,那么这个对象中的元素必须符合大于0 小于256
print(bytearray([256,1,2]))

#返回一个的“bytes”对象,返回bytes类型
bytes(&#39;中文&#39;,&#39;utf-8&#39;)

#检查对象是否可以被调用
def func():
    pass
print(callable(func))

#返回整数所对应的Unicode字符,chr(97)返回字符串&#39;a&#39;,而chr(8364)返回字符串&#39;€&#39;。
print(chr(126))

#是用来指定一个类的方法为类方法,类方法可以不实例化直接调用
class A:
    @classmethod
    def B(cls,arg1,):
        print(arg1)
A.B(1)
A().B(1)

#将源编译为代码或者AST对象。代码对象能够通过exec语句来执行或者eval()进行求值。
#源可以是正常字符串,字节字符串或AST对象。
expr = "5+5-1"
obj = compile(expr,"","eval")
print(eval(obj))

#返回值为real + imag * j的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数。
print(complex(1, 2))
print(complex(1))
print(complex("1+2j"))



# 参数是一个对象和一个字符串。 该字符串必须是对象属性之一的名称。
class A:
    def a1(self):
        print("a1")
    def a2(self):
        print("a2")

obj = A
print(dir(obj))
delattr(obj, "a1")
print(dir(obj))

#dir 返回对象中的方法
strs="aaa"
print(dir(strs))

#返回两个数值的商和余数
print(divmod(7,3))

#用于遍历序列中的元素以及它们的下标
print(enumerate([1,2,3]))#返回的是可迭代的对象
for i,j in enumerate((&#39;A&#39;,&#39;B&#39;,&#39;C&#39;)):
    print(i,j)

#将字符串str当成有效的表达式来求值并返回计算结果。
print(eval("1+2+3"))
print(eval("False or True"))

#字符串str当成动态语句块执行并返回结果
exec(&#39;a=1+2+3&#39;)
print(a)

#使用指定方法(方法,函数),过滤可迭代对象的元素
def add(arg):
    return arg > 3

for i in filter(add,[1,2,3,4,5]):
    print(i)

#浮点型
print(float(11))

#格式化显示 更多方法请参考官方说明
print(&#39;{:,.2f}&#39;.format(111111))

#根据传入的参数创建一个新的不可变集合
a = frozenset([1,2,3,4,5])
print(a)

#获取对象的属性值
class A():
    def __init__(self,):
        self.name = "123"
b = A()
print(getattr(b,&#39;name&#39;))

#返回当前作用域内的全局变量和其值组成的字典
print(globals())

#检查对象是否含有属性
class A():
    def __init__(self,):
        self.name = "123"
b = A()
print(hasattr(b,&#39;name&#39;))

#哈希值计算
#在当前环境中是唯一的
print(hash(&#39;Hello&#39;))

#help帮助
def funcs(args):
    """
    Function description
    :param args: args = list
    :return:
    """
    pass
print(help(funcs))

#转换16进制
print(hex(44))

#显示对象的标识符
print(id("123"))

#input标准输入
s = input("user name:")
print(s)

#int返回整数
print(int(1.2))
print(int("2"))

#判断对象是否是类或者类型元组中任意类元素的实例
print(isinstance("1",int))
print(isinstance(1.1,(int,float)))


#判断类是否是另外一个类或者类型元组中任意类元素的子类
print(dir(str))
print(issubclass(bytearray,str))
print(issubclass(bool,int))

#根据传入的参数创建一个新的可迭代对象
a = iter(&#39;12345&#39;)
print(next(a))
print(next(a))

#返回对象的长度len
a = [1,2,3,4]

#转换列表
print(list("abcd"))

#返回当前作用域内的局部变量和其值组成的字典
def A():
    print(locals())
    s = 1
    print(locals())
A()

#使用指定方法去作用传入的每个可迭代对象的元素,生成新的可迭代对象
def add(x):
    return x+100
lists = [1,2,3,4]
for i in map(add,lists):
    print(i)

#max:返回最大值
print(max(1,2,3))
print(max([1,2,3,4]))

#在进行切片并赋值数据时,不需要重新copy原列表数据,可以直接映射原数据内存;
s = memoryview(b&#39;abcd&#39;)
print(s[1])

#返回最小值
print(min(1,2,3))
print(min([2,3]))

#返回可迭代对象中的下一个元素值
a = iter(&#39;1234&#39;)
print(next(a))

#创建一个新的object对象(新式类)
class B(object):
    pass

#转化成8进制数字符串
print(oct(10))

#open文件操作
file = open(&#39;test.txt&#39;,encoding="utf-8")

#ord:返回Unicode字符对应的整数
print(ord("A"))

#幂运算

print(pow(2,3))

#标准输出
print()

#property:标示属性的装饰器
#类中使用具体方法请百度,或者等待后续更新
property

#range:根据传入的参数创建一个新的range对象
range(10)
range(1,10)

"""repr()函数得到的字符串通常可以用来重新获得该对象,repr()的输入对python比较友好。
通常情况下obj==eval(repr(obj))这个等式是成立的。"""
obj=&#39;Python&#39;
print(eval(repr(obj)))


#翻转序列
a = reversed([1,2,3,4,5])
print(list(a))

#round:对浮点数进行四舍五入求值
print(round(1.5))

#set 转换成集合
print(set([1,2,3]))

#setattr:设置对象的属性值
class A():
    def __init__(self,age):
        self.age = age
s = A(11)
print(s.age)
setattr(s,&#39;age&#39;,22)
print(s.age)

#根据传入的参数创建一个新的切片对象
c1 = slice(3)
c2 = slice(2,4)
c3 = slice(0,5,2)
s = [1,2,3,4,5,6]
print(s[c1])
print(s[c2])
print(s[c3])


#排序,返回一个新的列表默认按字符ascii码排序
a = [4,3,2,1,7]
print(sorted(a))

#标示方法为静态方法的装饰器
class B(object):
    def __init__(self,age):
        self.age = age

    @staticmethod
    def hello(args):
        print(args)

B.hello("Hello World")

#字符串类型
print(str(123))

#求和
print(sum([1,2,3,4]))

#根据传入的参数创建一个新的子类和父类关系的代理对象
class A(object):
    def __init__(self):
        print("我是 A Clase")

class B(A):
    def __init__(self):
        print("我是 B Class")
        super().__init__()
b = B()

#元祖
tuple([1,2,3,4])


#type 返回对象的类型
print(type([1]))
print(type("1"))

#返回当前作用域内的局部变量和其值组成的字典,或者返回对象的属性列表
def func():
    print(vars())
    s = 1
    print(vars())
func()

#聚合传入的每个迭代器中相同位置的元素,返回一个新的元组类型迭代器
list1 = [1,2,3]
list2 = ["A","B","C","D"]
print(zip(list1,list2))
for i in zip(list1,list2):
    print(i)

#__import__:动态导入模块
__import__


更多简学Python第三章__函数式编程、递归、内置函数 相关文章请关注PHP中文网!

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