Python编程学习8:python函数详解

1. 函数的形参和实参: 

定义函数时的参数为形参,调用函数时的参数为实参。下例中,para1为形参,10为实参

def func1(para1):
    area = 3.14*para1**2
    return area
s = func1(10)
print(s)
314.0


2. 函数文档:写函数文档是个好习惯。最好使用三引号,方便换行

函数文档可以让别人更好地理解自己的函数,注意和注释是有区别的。可以使用func.__doc__ 获取函数的文档。

def func1(para1):
    """获取圆的半径para1,返回圆的面积area"""
    # 此处PI取3.14
    area = 3.14*para1**2
    return area
print(func1(10))
print(func1.__doc__)
314.0
获取圆的半径para1,返回圆的面积area

注意:以#号开头的不是文档,是注释,func.__doc__方法无法获取注释内容。

         文档要出现在函数的第一行(前面可以有注释。),出现在其他地方不是文档,__doc__方法无法获取。

def func2(para1):
    # 此处PI取3.14
    "获取圆的半径para1"
    area = 3.14*para1**2
    "返回圆的面积area"
    return area
print(func2(10))
print(func2.__doc__)

314.0
获取圆的半径para1
def func2(para1):
    # 此处PI取3.14
    area = 3.14*para1**2
    "获取圆的半径para1,返回圆的面积area"
    return area
print(func2(10))
print(func2.__doc__)

314.0
None

3. 参数定制赋值

    有时,函数参数较多,传入实参时容易弄乱顺序,造成计算错误,如下实例,第二次调用func3(2,3,5)弄错了底和高,导致面积计算错误。可使用关为每个形参指定赋值。如

def func3(d1,d2,h):
    "计算梯形面积,d1是上底,d2是下底,h是高"
    s = (d1 + d2) * h * 0.5
    return s
#计算上底为3,下底为5,高为2的梯形面积
print(func3(3,5,2))
print(func3(2,3,5))
print(func3(h=2,d1=3,d2=5))

8.0
12.5
8.0


4. 默认参数:部分函数的参数可以事先设置一个默认值,如果不传入此参数,代表使用默认值。

def func1(para1 = 10):
    "获取圆的半径para1,返回圆的面积area"
    # 此处PI取3.14
    area = 3.14*para1**2
    return area
print(func1())
print(func1(5))

314.0
78.5

5. 位置参数:参数前加*,形如*args,代表要传入的参数是一个元组, 长度不定

def func4(a,b,*args):
    sum1 = 0
    sums2 = a + b
    print(type(args))
    for i in range(len(args)):
        sum1 += args[i]
    return sum1,sums2
print(func4(2,3,4,6,7))

<class 'tuple'>
(17, 5)

注意:在位置参数后还要传入其他参数,需在调用时指定赋值, 否则会报错。

def func5(*args,a,b):
    sum1 = 0
    sums2 = a + b
    for i in range(len(args)):
        sum1 += args[i]
    return sum1,sums2
print(func5(2,3,4,6,7))

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-19-061daa652241> in <module>()
      6         sums += args[i]
      7     return sum1,sums2
----> 8 print(func5(2,3,4,6,7))

TypeError: func5() missing 2 required keyword-only arguments: 'a' and 'b'
print(func5(2,3,4,a=6,b=7))
(9, 13)

6. 关键字参数:形如**kwargs,代表要传入的参数是一个字典, **kwargs允许你将不定长度的键值对作为参数传递给一个函数.
def func6(**kwargs):
    sent1 = ''
    for key in kwargs.keys():
        sent1 += ' '
        sent1 += kwargs[key]

    return sent1

myDict = {0:'LBJ',1:'will',2:'win',3:'another',5:'champion'}
print(func6(w1 = 'LBJ', w2 = 'will', w3 = 'win', w4 = 'another', w5 = 'champion'))

 LBJ will win another champion
print(func6(myDict))
TypeError                                 Traceback (most recent call last)
<ipython-input-49-b51c5b98f1f2> in <module>()
----> 1 print(func6(myDict))

TypeError: func6() takes 0 positional arguments but 1 was given


7. 函数与过程:有返回值称为函数,没有返回值称为过程,python严格来说只有函数,没有写return时,默认返回None.

def func4(a,b,*args):
    sum1 = 0
    sums2 = a + b
    for i in range(len(args)):
        sum1 += args[i]
print(func4(2,3,4,6,7))

None

8. 函数变量的作用域:局部和全局变量;函数中可以随意访问全局变量. 

     (1)  但修改全局变量需注意,python会创建一个新的局部变量代替,名字和全局变量一样(屏蔽的方式)。所以一般不要试图在函数内部修改全局变量。

def func7(price,discount=0.7):
    print("原有价格",price,'变量id是',id(price))
    new_price = price*discount
    price = 89
    print("修改后的价格1",price,'变量id是',id(price))
    return new_price

price = 99
print("折后价格",func7(price))
print("修改后的价格2",price,'变量id是',id(price))

原有价格 99 变量id是 1683944976
修改后的价格1 89 变量id是 1683944656
折后价格 69.3
修改后的价格2 99 变量id是 1683944976
    (2)若确实想在函数中修改全局变量,可借用global
def func7(discount=0.7):
    global price
    print("global使用测试开始...")
    
    print("原有价格",price,'变量id是',id(price))
    new_price = price*discount
    
    price = 89
    print("修改后的价格1",price,'变量id是',id(price))
    return new_price


price = 99
print("折后价格",func7(price))
print("修改后的价格2",price,'变量id是',id(price))

price = 99
print("折后价格",func7(price))
print("修改后的价格2",price,'变量id是',id(price))
注意:global变量是不必也不能作为函数参数的, 否则可能出错
def func7(price,discount=0.7):
    global price
    new_price = price*discount    
    return new_price

price = 99
print("折后价格",func7(price))

 File "<ipython-input-9-5af6c32b3c4a>", line 2
    global price
    ^
SyntaxError: name 'price' is parameter and global

(3)内嵌函数:func2嵌套在func1函数中,这就是内嵌函数

        内部函数整个作用域都在外部函数之内,内部函数可以随意访问外部函数的变量/参数

def func1():
    print("func1函数被调用")
    def func2():
        print("func2函数被调用")
    func2()    

func1()

func1函数被调用
func2函数被调用

(4)闭包:一种函数式编程范式。

     在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。如下例子:内部函数funcY调用了外部函数的临时变量x, 而外部函数funcX返回funcY的引用。

def funcX(x):
    def funcY(y):
        return x + y
    return funcY

z = funcX(1)
print(type(z))
print(z(3))
print(funcX(5)(7))

<class 'function'>
4
12

(5)nonlocal的使用

def funcX():
    x = 8
    def funcY():
        x *= x
        return x
    return funcY()

funcX()

---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-28-09432caee8da> in <module>()
      6     return funcY()
      7 
----> 8 funcX()

<ipython-input-28-09432caee8da> in funcX()
      4         x *= x
      5         return x
----> 6     return funcY()
      7 
      8 funcX()

<ipython-input-28-09432caee8da> in funcY()
      2     x = 8
      3     def funcY():
----> 4         x *= x
      5         return x
      6     return funcY()

UnboundLocalError: local variable 'x' referenced before assignment

内部函数对外部函数的局部变量进行修改时,需注意陷阱,如上实例, 道理和全局变量 VS 局部变量类似。使用nonlocal可解决

def funcX():
    x = 8
    def funcY():
        nonlocal x
        x *= x
        return x
    return funcY()

funcX()

64

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值