python小白学习笔记(廖老师)10.1

写博客的初衷就是希望自己能坚持吧,当作一个小打卡啦~ ps:大神绕路,很初级很白痴
同时记录一些易错和易忘的知识点,以后复习翻着看看。
另:廖雪峰老师的网站刚刚接触,感觉很干货的样子,在这里推荐一下下~
注:本博客参考廖雪峰老师的网站
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000

day3:

一、调用函数

1.可以直接从Python的官方网站查看文档:

http://docs.python.org/3/library/functions.html

也可以在交互式命令行通过help(abs)查看abs函数的帮助信息。

2.调用函数的时候,如果传入的参数不对,会报TypeError的错误。

3.常用函数——数据类型转换

>>> s=int('123')
>>> b=s/2
>>> b
61.5

二、定义函数

1.在Python中,定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。

def my_abs(x):
    if x >= 0:
        return x
    else:
        return -x

2.实际上pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来。

3.参数检查

调用函数时,如果参数个数不对,Python解释器会自动检查出来,并抛出TypeError;
但是如果参数类型不对,Python解释器就无法帮我们检查。

我们可以通过修改my_abs的定义,对参数类型做检查,只允许整数和浮点数类型的参数。数据类型检查可以用内置函数isinstance()实现:

isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()

isinstance(object, classinfo)        //如果对象的类型与参数二的类型(classinfo)相同则返回 True,否则返回 False
>>> def my_abs(x):
    if not isinstance(x,(int,float)):
        raise TypeError('bad operand type')
    if x>=0:
        return x
    else:
        return -x
    
>>>my_abs('a')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 3, in my_abs
TypeError: bad operand type

4.返回多个值

import math

def move(x,y,step,angle=0):
    nx=x+step * math.cos(angle)
    ny=y-step * math.sin(angle)
    return nx,ny

x, y = move(100, 100, 60, math.pi / 6)
print(x, y)

在这里插入图片描述
Python的函数返回多值其实就是返回一个tuple,但写起来更方便。

>>> r = move(100, 100, 60, math.pi / 6)
>>> print(r)
(151.96152422706632, 70.0)

三、函数的参数

1.位置参数:必须传入的参数

例:计算x的平方

def power(x):                //x即为位置参数
    return x * x

2.默认参数:用于简化函数的调用

注:(1)默认参数不能放在必选参数前面
(2)当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。

def power(x, n=2):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s

这样,当我们调用power(5)时,相当于调用power(5, 2),调用n不等于2时又恢复原样:

>>> power(5)
25
>>> power(5, 2)
25
>>> power(5,3)
255

(3)定义默认参数要牢记一点:默认参数必须指向不变对象!或者用None修改可变对象为不变对象来实现

def add_end(L=None):
    if L is None:
        L = []
    L.append('END')
    return L

>>> add_end()
['END']
>>> add_end()
['END']

3.可变参数

可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。

定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数。

//给定一组数字a,b,c……,请计算a2 + b2 + c2 + ……

def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

>>> calc(1, 2, 3)
14
>>> calc(1, 3, 5, 7)
84

>>> nums = [1, 2, 3]            //Python允许在listtuple前面加一个*号,把listtuple的元素变成可变参数传进去:
>>> calc(*nums)
14

3.关键字参数

可变参数 允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple

关键字参数 允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict,可以扩展函数的功能。

def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)

>>> person('Bob', 35, city='Beijing')
name: Bob age: 35 other: {'city': 'Beijing'}
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}

和可变参数类似,也可以先组装出一个dict,然后,把该dict转换为关键字参数传进去:

>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}

4.命名关键字参数

如果要限制关键字参数的名字,就可以用命名关键字参数。

注:命名关键字参数必须传入参数名。

如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了。

def person(name, age, *, city, job):
    print(name, age, city, job)

>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer

def person(name, age, *args, city, job):
    print(name, age, args, city, job)

5.参数组合

参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。

对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的。

错题:试写一个累乘函数

//错误示范
# -*- coding: utf-8 -*-
def product(*nums):
   multi=1
   for n in nums:
      multi=multi*n
   return multi

#测试
print('product(5) =', product(5))
print('product(5, 6) =', product(5, 6))
print('product(5, 6, 7) =', product(5, 6, 7))
print('product(5, 6, 7, 9) =', product(5, 6, 7, 9))
if product(5) != 5:
    print('测试失败!')
elif product(5, 6) != 30:
    print('测试失败!')
elif product(5, 6, 7) != 210:
    print('测试失败!')
elif product(5, 6, 7, 9) != 1890:
    print('测试失败!')
else:
    try:
        product()
        print('测试失败!')
    except TypeError:
        print('测试成功!')

product(5) = 5
product(5, 6) = 30
product(5, 6, 7) = 210
product(5, 6, 7, 9) = 1890
测试失败!

错误原因:测试中try:函数中至少要有一个必选参数,才能测试成功

def product(x,*nums):
   s=x
   for i in nums:
      s*=i
   return s

product(5) = 5
product(5, 6) = 30
product(5, 6, 7) = 210
product(5, 6, 7, 9) = 1890
测试成功!

四、递归函数

在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

1.使用递归函数需要注意防止栈溢出,由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。

2.针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环。

Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。

尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。

猜你喜欢

转载自blog.csdn.net/weixin_41206209/article/details/82917148