开发技术--浅谈Python函数

开发|浅谈Python函数

函数在实际使用中有不少不同的小九九,我将从最基础的函数内容,延伸出函数的高级用法。此文非科普片~~python

前言

目前全部的文章思想格式都是:知识+情感。
知识:对于全部的知识点的描述。力求不含任何的自我感情色彩。
情感:用我本身的方式,解读知识点。力求通俗易懂,完美透析知识。

正文

首先介绍函数是什么,接着走进函数,而且发现函数的高级使用方法,最后列出经常使用的Python的内置函数。linux

函数是什么?

1.函数,在代码执行的是不执行,只有在调用函数的时候才会执行。闭包

2.函数使用关键字: def进行定义,看下面:并发

In [1]: def demo():
   ...:     print('I am a demo ...')
   ...:

In [2]: demo()
I am a demo ...

3.书写函数的时候,默认返回值是:None。而且须要书写函数的说明文档。函数内部在必要的位置进行写注释,对应的执行内容说明app

函数基本参数

1.函数传递数据的参数
1)在函数括号中书写的是形参
2)调用函数传递的数据,叫作实参函数

2.函数形参的分类
1)位置参数,经过书写数据的前后位置进行数据的传输。看代码~传递参数的顺序大数据

2)默认参数,直接在函数中进行默认指定数据,函数调用的时候,能够传递也能够不传数据。看下面,sex属于默认参数。ui

3)关键字参数,在调用函数的时候,直接指定形参的名字进行传输数据。看下面,age属于关键字传参。设计

In [3]: def func(name, age, sex='male'):
   ...:     print('My name is %s,I am %s years old, I am a %s.' %(name, age, sex))
   ...:

In [4]: func('rongming', age=18)
My name is rongming,I am 18 years old, I am a male.

4)非固定参数
使用 args , * kwargs 表示
其中,*args 能够传递任意非键值对数据,而且存储为元组形式code

    • kwargs 保存传递的键值对数据,使用字典的形式进行存储,很是方便,时间使用次数很是多~~

3.函数做用域
1)规则:只要是进行了代码的缩进(一个tab键或者四个空格,大多数都是有做用域的产生。)
2)函数内部与函数外部,所包含的变量不在同一个做用域,变量的查找范围是LEGB
表示在函数内部调用变量,优先去本身当前区域(locals)找,接着去函数嵌套空间中(enclosing function)找,再接着去全局空间(globals)找,最后去内置模块空间(builtins)找。
3)查看局部变量与全局变量方法:
局部变量 locals()
全局变量 globals()
4)函数内部使用外部的变量
使用, global,例如: global name # 在函数内部声明全局变量name,不推荐
可使用nonlocal, 例如:nonlocal name,一样也能够,推荐

4.函数中的
注意:函数或者说Python中更改数据产生的坑均可以是不可变数据类型,因此须要从底层认清楚不可变数据类型的存储方式,必定要记住不可变数据类型只是相对于不可变数据类型中元素的不可变。
注意:若是在函数内部使用函数外部的字典或者列表 这些可变数据类型,在函数中能够修改函数外的内容,没想到吧~~~

高阶函数

高阶函数是什么?

定义:接收函数为参数,或者把函数做为结果返回的函数是高阶函数。

嵌套函数

嵌套函数就是函数里面还写函数的样子~
看一下示例:(func函数里面写inner函数)

def func():
    a = 10

    def inner():
        print(a)
    return inner

匿名函数

匿名函数使用关键字: lambda。看下面的例子:

addfunc = lambda x: x*3

注意:因为匿名函数能够将函数简写为一行,而且你们看着逼格高,因此在某些时候,应用仍是比较多的。
例子: map() 与匿名函数应用场景场景

s = map(lambda x: x+10, [i for i in range(10)])
for i in s:
    print(i)
    
10
11
12
13
14
15
16
17
18
19

递归函数

1.递归函数: 递归表示在函数执行的时候,内部调用自身执行。
注意: 函数退出是否须要执行代码,也就是函数在调用自身的以后还有没有代码执行,超过递归默认次数,会产生栈溢出。

2.知识点:
pycharm里栈溢出报错是:
Process finished with exit code -1073741571 (0xC00000FD)

** linux栈溢出报错是:**
Segmentation fault (core dumped)

3.递归栈容量:

OS          default             sys.setrecursionlimit(100000)
win             996                2512
linux           998               16361
linux默认递归栈容量是8M,能够经过ulimit -s扩充。

闭包

注意:必定要注意闭包的定义是什么!!!
1.闭包的产生条件,在嵌套函数中才会出现,闭包表示匿名函数,闭包的本质属于函数做用域的延伸(不局限于函数体内的做用域),只要在嵌套函数中内部函数能够访问自己以外的全局变量就称为闭包。
闭包中,内部函数访问的外部变量叫作自由变量。
实现闭包的例子:

In [4]: def func():
   ...:     """闭包"""
   ...:     numbers = []
   ...:
   ...:     def inner(num):
   ...:         numbers.append(num)
   ...:         return numbers
   ...:
   ...:     return inner
   ...:

In [5]: num = func()

In [6]: num(10)
Out[6]: [10]

In [7]: num(11)
Out[7]: [10, 11]

In [8]: num(12)
Out[8]: [10, 11, 12]

2.闭包的底层
闭包能够实现对于自由变量的调用,关键点在于闭包函数存在一个Python的__ code 属性(对代码编译后的函数的定义体)中,存在一个函数的 closure __的属性,将自由变量进行绑定。
看下面的示例:

In [15]: num.__closure__
Out[15]: (<cell at 0x000001A723D50348: list object at 0x000001A7234789C8>,)

In [16]: num.__closure__[1]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-16-56cdbd3f3ffc> in <module>
----> 1 num.__closure__[1]

IndexError: tuple index out of range

In [17]: num.__closure__[0].cell_contents  # 取到的num.__closure__[0]属于cell对象,存在cell_contents属性
Out[17]: [10, 11, 12]
In [18]: num.__code__.co_freevars   # 函数体中的,绑定的自由变量
Out[18]: ('numbers',)

In [19]: num.__code__.co_varnames  # 函数体内部的本地变量
Out[19]: ('num',)

装饰器(语法糖)

注意:装饰器不要懵逼~~给我一块儿透析它
1.使用@加上函数名字,而且放在另外一个函数上面的样式就是说,搞了个装饰器,别蒙蔽,如今就已经认识装饰器了~

2.装饰器使用的是闭包的思想,既然是闭包的思想,那么是否是会在被装饰的函数的函数,返回一个对应函数内部的函数名(地址)。
重点:此时被装饰的函数就再也不是你们肉眼看的函数了,而是被返回装饰的函数内部函数,一旦调用,就先执行了装饰器里面的内容,在执行函数的执行内容。(仍是看代码吧~)

3.时间装饰器

In [26]: import time
    ...: import functools
    ...:
    ...:
    ...: def timer(func):
    ...:     @functools.wraps(func)
    ...:     def inner(*args, **kwargs):
    ...:         start = time.time()
    ...:         res = func(*args, **kwargs)
    ...:         end = time.time()
    ...:         print('This code used %s sec.' % (end - start))
    ...:         return res
    ...:     return inner
    ...:
    ...:
    ...:
    ...: @timer
    ...: def func(num1, num2):
    ...:     time.sleep(3)
    ...:     return num1 + num2
    ...:

In [27]: func(10, 33)
This code used 3.008526563644409 sec.
Out[27]: 43

生成器

1.生成器,全部的生成器都是迭代器,generator,只须要将列表生成式变为()便可,看下面

In [28]: s = [i for i in  range(10)]

In [29]: s
Out[29]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [30]: b = (i for i in range(10))

In [31]: b
Out[31]: <generator object <genexpr> at 0x000001A7223B0228>

2.生成器, 防止大数据生成,省空间,在作大数据生成的时候,能够保证,用多少我产生多少,占用多大的空间。产生的用完了就会报错StopIteration。

In [41]:  b = (i for i in range(10))

In [42]: next(b)
Out[42]: 0

In [43]: next(b)
Out[43]: 1

In [44]: for i in b:
    ...:     print(i)
    ...:
2
3
4
5
6
7
8
9

In [45]: next(b)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-45-adb3e17b0219> in <module>
----> 1 next(b)

StopIteration:

函数生成器

1.函数生成器,保证了函数能够,在执行一半的时候,干点其余的事,而且能够将干的事返回到函数中,这也是协程的思想。全部的生成器都是迭代器。

2.实现函数生成器,只须要在函数内部添加yield便可。而且知识函数外部传递参数到函数内部,在初始化生成器的时候,须要使用__next__ 调用生成器,此时发送None到yield启动生成器,就可使用next()进行调用了!其中,send() 表示调用生成器,并发送数据。

3看代码:

In [46]: def gen(a):
    ...:     while a < 10:
    ...:         yield a
    ...:         a += 1
    ...:

In [47]: gen(5)
Out[47]: <generator object gen at 0x000001A723309228>

In [48]: b = gen(5)

In [49]: next(b)
Out[49]: 5

In [50]: next(b)
Out[50]: 6

In [51]: for i in b:
    ...:     print(i)
    ...:
7
8
9

迭代器

1.迭代器的构建使用:iter() ,能够将可迭代对象变为迭代器。

2.可使用isinstance()判断是否是iterator,可使用next()调用,for循环调用。

3.例子:

In [52]: s = iter(i for i in range(10))

In [53]: s
Out[53]: <generator object <genexpr> at 0x000001A7226116D8>

In [54]: next(s)
Out[54]: 0

In [55]: next(s)
Out[55]: 1

In [56]: for i in s:
    ...:     print(i)
    ...:
2
3
4
5
6
7
8
9

In [57]: next(s)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-57-61c30b5fe1d5> in <module>
----> 1 next(s)

StopIteration:

python内置函数

Python 的内置函数不少,可是仍是能够排列一个顺序的,因此下面我将我本身经常使用的函数进行一个顺序排列:

print()
id()
enumerate()
str() 字符的集合
list() 元素的集合
bytes()
map()
sum()
isinstance()
next()
abs()
max()
min()
bool()
all() iterable is bool()
any() iterable is bool()
bytearray()
complex()
divmod()
eval() 字符串数据类型转换成为Python的数据类型
exec() 执行字符串
exit()
filter() 符合条件的进行过滤
zip()

结束语

**Python的函数设计不少内容,实现功能要么是函数,要么是对象,因此有一些底层的内容,须要多加 挖掘,好比闭包的 __ code __,还有个自由变量等等。**
感慨:路还很长,本身最须要的是时间与经历,加上一个不错的理解能力~~

相关文章
相关标签/搜索