Python基础--函数

在开发程序时,需要多次使用某块代码,这时可以将这部分代码独立为一个模块,这便是函数。函数可以提高编码的效率和代码复用。一个类中函数名不能重复使用。

def 函数名():
      代码逻辑

例:求0~100累加和

def sum(num):
    result = 0
    while num > 0:
        result += num
        num -= 1
    return result

print("---调用sum函数---")
a = sum(100)
print("求0到100之和:%d"%a)

输出:
---调用sum函数---
求0到100之和:5050

局部变量

  • 局部变量,就是在函数内部定义的变量
  • 不同的函数,可以定义相同的名字的局部变量,但是相互不会产生影响
  • 局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储,这就是它的作用
def test1():
    avr = 100
    print("test1中的avr=%d"%avr)

def test2():
    avr = 300
    print("test2中的avr=%d"%avr)

test1()
test2()

输出:
test1中的avr=100
test2中的avr=300

全局变量

  • 在函数外边定义的变量叫做全局变量
  • 全局变量能够在所有的函数中进行访问
  • 如果在函数中修改全局变量,那么就需要使用global进行声明,否则出错:UnboundLocalError: local variable 'a' referenced before assignment
  • 如果全局变量的名字和局部变量的名字相同,那么使用的是局部变量的
a = 100     #定义全局变量
def test1():
    global a
    print('test1修改之前a=%d'%a)
    a = 188
    print('test1修改之后a=%d'%a)

def test2():
    print("---test2中---a=%d"%a)

#调用函数
test1()
test2()

输出:
test1修改之前a=100
test1修改之后a=188
---test2中---a=188

对于不可修改的全局变量而言,使用global来声明其实在是修改其内存中的指向,即修改了地址。

对于可变类型(列表、字典)的全局变量而言,因为其指向的数据是可以修改的,所以不必用global声明,就可以修改。

函数常见的几种参数

  • 缺省参数。调用函数时,缺省参数的值如果没有传入,则使用默认值;默认参数值一定要位于参数列表最后,否则报错SyntaxError: non-default argument follows default argument
def printInfo(name,age = 18):
    print("name: ",name,end=" ,")
    print("age: ",age)

printInfo(name="AOC")
printInfo(age=18,name="Dail")
#printInfo(age=18,"Dail") #SyntaxError: positional argument follows keyword argument
#  age是关键字参数,“Dail”是位置参数

输出:
    name:  AOC ,age:  18
    name:  Dail ,age:  18

注:关键字参数必须跟在位置参数之后,因为Python函数解析参数时,按照顺序来的,必须先满足位置参数,再考虑其他可变参数。

  • 不定长参数。在某些场景下函数处理参数可能比最初的要多,这些变化的参数叫不定参数,声明时不会命名。
    def functionname([formal_args,] *args, **kwargs):
       "函数_不定长参数"
       pass
       return [expression]

*args存放所有未命名的变量参数,args为元组;**kwargs存放命名参数,kwargs为字典。

#可变参数
def fun(a,b,*args,**kwargs):
    "不定长参数函数"
    print("a = ",a)
    print("b = ",b)
    print("*args = ",args)
    print("**kwargs = ",kwargs)

fun(1,2,3,4,'A',i=5,j=6,k=7)

输出:
    a =  1
    b =  2
    *args =  (3, 4, 'A')
    **kwargs =  {'i': 5, 'j': 6, 'k': 7}
  • 引用参数。Python中的函数传递参数是引用传递,不是我们以为的值传递。对于不可变类型的变量而言,运算不会影响到变量自身。对于可变类型而言,在函数体中的运算可能会更改传入的参数变量。
#引用参数
def test(a):
    "---自增---"
    a += a
    print('调用时test---a=',a,'id(a)=',id(a))

num = 1
print("调用前id(num)=",id(num))
test(num)
print("调用后id(num)=",id(num),"num = ",num)
print('='*20,'可变类型参数')
alist = ['1','2']
print("调用前id(alist)=",id(alist))
test(alist)
print("调用后id(alist)=",id(alist),"alist = ",alist)

输出:
    调用前id(num)= 10919328
    调用时test---a= 2 id(a)= 10919360
    调用后id(num)= 10919328 num =  1
    ==================== 可变类型参数
    调用前id(alist)= 140681290722120
    调用时test---a= ['1', '2', '1', '2'] id(a)= 140681290722120
    调用后id(alist)= 140681290722120 alist =  ['1', '2', '1', '2']

递归函数

一个函数在其内部不停的调用自身,这便是递归函数。

def calNum(num):
    if num >= 1:
        result = num + calNum(num-1)
    else:
        result = 0
    return result

print("结果:",calNum(100))

输出:
    结果: 5050

 匿名函数

用lambda关键词能创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤。lambda函数的语法只包含一个语句,如下:

 lambda [arg1 [,arg2,.....argn]]:expression    #expression结果作为返回值
def test(a,b,func):
    result = func(a,b)
    return result
num = test(10,40,lambda x,y:x+y)
print("计算结果:%d"%num)

输出:
    计算结果:50

eval() --内置函数

  eval(expression, globals=None, locals=None)  --- 官方文档中的解释是,将字符串str当成有效的表达式来求值并返回计算结果。globals和locals参数是可选的,如果提供了globals参数,那么它必须是dictionary类型;如果提供了locals参数,那么它可以是任意的map对象。

exp = input("输入一个表达式:") #exp为字符串
print("输出exp: ",exp)
#eval将str解析为有效的表达式、并返回计算结果
print("eval输出结果: ",eval(exp))

输出:
    输入一个表达式:5*5
    输出exp:  5*5
    eval输出结果:  25

eval()滥用会有风险

Python作为动态语言,有时交互时需要用户输入一个表达式。如果用户输入:__import__('os').system('dir'),那么当前目录文件将全部暴露给用户,用户这时可以继续访问文件,甚至删除当前目录的文件。

规避方法:

1、自行写检查函数;

2、使用ast.literal_eval:自行查看DOCUMENT

3、很多其它好文:Restricted "safe" eval(Python recipe)

 

posted @ 2018-11-24 18:46  今生遇见前世  阅读(186)  评论(0编辑  收藏  举报