本节内容

1. 函数基本语法及特性

2. 参数与局部变量

3. 返回值

       嵌套函数

4.递归

5.匿名函数

6.函数式编程介绍

7.高阶函数

8.内置函数

 

 温故知新                                                                                  

1. 集合

主要作用: 

  1. 去重
  2. 关系测试, 交集\差集\并集\反向(对称)差集
 1 >>> a = {1,2,3,4}
 2 >>> b = {3,4,5,6}
 3 >>> a
 4 {1, 2, 3, 4}
 5 >>> type(a)
 6 <class 'set'>
 7 >>> a.symmetric_difference(b)
 8 {1, 2, 5, 6}
 9 >>> b.symmetric_difference(a)
10 {1, 2, 5, 6}
11 >>> 
12 >>> 
13 >>> a.difference(b)
14 {1, 2}
15 >>> a.union(b)
16 {1, 2, 3, 4, 5, 6}
17 >>> a.issubset(b)
18 False
19 >>> 
set_operation

2. 元组  

只读列表,只有count, index 2 个方法。

作用:如果一些数据不想被人修改, 可以存成元组,比如身份证列表。

3. 字典

key-value对特性:

  1. 无顺序
  2. 去重
  3. 查询速度快,比列表快多了
  4. 比list占用内存多

为什么会查询速度会快呢?因为他是hash类型的,那什么是hash呢?

哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的哈希值可以检验数据的完整性。一般用于快速查找和加密算法

dict会把所有的key变成hash 表,然后将这个表进行排序,这样,你通过data[key]去查data字典中一个key的时候,python会先把这个key hash成一个数字,然后拿这个数字到hash表中看没有这个数字, 如果有,拿到这个key在hash表中的索引,拿到这个索引去与此key对应的value的内存地址那取值就可以了。

待续 ...

4. 字符编码

先说python2

  1. py2里默认编码是ascii。
  2. 文件开头那个编码声明是告诉解释此代码(文件)的程序 以什么编码格式 把这段代码读入到内存(存储于内存的这段代码是以bytes二进制格式存储的,但是即使是2进制流,也可以按不同的编码格式转成2进制流)。
  3. 如果在文件头声明了#_*_coding:utf-8_*_,就可以写中文了, 不声明的话,python在处理这段代码时按ascii,显然会出错, 加了这个声明后,里面的代码就全是utf-8格式了。
  4. 在有#_*_coding:utf-8_*_的情况下,你在声明变量如果写成name=u"大保健",那这个字符就是unicode格式,不加这个u,那你声明的字符串就是utf-8格式。
  5. utf-8 to gbk怎么转,utf8先decode成unicode,再encode成gbk。

再说python3

  1. py3里默认文件编码就是utf-8,所以可以直接写中文,也不需要文件头声明编码了。
  2. 你声明的变量默认是unicode编码,不是utf-8, 因为默认即是unicode了(不像在py2里,你想直接声明成unicode还得在变量前加个u), 此时你想转成gbk的话,直接your_str.encode("gbk")即可以。
  3. 但py3里,你在your_str.encode("gbk")时,感觉好像还加了一个动作,就是就是encode的数据变成了bytes里,我擦,这是怎么个情况,因为在py3里,str and bytes做了明确的区分,你可以理解为bytes就是2进制流,你会说,我看到的不是010101这样的2进制呀, 那是因为python为了让你能对数据进行操作而在内存级别又帮你做了一层封装,否则让你直接看到一堆2进制,你能看出哪个字符对应哪段2进制么。  
  4. 那你说,在py2里好像也有bytes呀,是的,不过py2里的bytes只是对str做了个别名(python2里的str就是bytes, py3里的str是unicode),没有像py3一样给你显示的多出来一层封装,但其实其内部还是封装了的。 这么讲吧, 无论是2还是三, 从硬盘到内存,数据格式都是 010101二进制到-->b'\xe4\xbd\xa0\xe5\xa5\xbd' bytes类型-->按照指定编码转成你能看懂的文字

编码应用比较多的场景应该是爬虫了,互联网上很多网站用的编码格式很杂,虽然整体趋向都变成utf-8,但现在还是很杂,所以爬网页时就需要你进行各种编码的转换,不过生活正在变美好,期待一个不需要转码的世界。

 

步入正题:

   1. 函数基本语法及特性                                                

函数是什么?

函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,具体区别,我们后面会讲,编程中的函数在英文中也有很多不同的叫法。在BASIC中叫做subroutine(子过程或子程序),在Pascal中叫做procedure(过程)和function,在C中只有function,在Java里面叫做method。

定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可。

特性:

  1. 减少重复代码
  2. 使程序变的可扩展
  3. 使程序变得易维护

语法定义

def sayhi():                             # sayhi 函数名
    print("Hello, I'm nobody!")
 
sayhi()                                    # 调用函数

 可以带参数

# 下面这段代码
a,b = 5,8
c = a**b
print(c)
 
 
# 改成用函数写
def calc(x,y):
    res = x**y
    return res                   # 返回函数执行结果
 
c = calc(a,b)                   # 结果赋值给c变量
print(c)

 

    2. 函数参数与局部变量                                                        

形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量。

实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值。

day03 - Python基础3

 

默认参数

def stu_register(name,age,country,course):
    print("----注册学生信息------")
    print("姓名:",name)
    print("age:",age)
    print("国籍:",country)
    print("课程:",course)
 
stu_register("王山炮",22,"CN","python_devops")
stu_register("张叫春",21,"CN","linux")
stu_register("刘老根",25,"CN","linux")

发现 country 这个参数 基本都 是"CN", 就像我们在网站上注册用户,像国籍这种信息,你不填写,默认就会是 中国, 这就是通过默认参数实现的,把country变成默认参数非常简单。

def stu_register(name,age,course,country="CN"):

这样,这个参数在调用时不指定,那默认就是CN,指定了的话,就用你指定的值。

另外,你可能注意到了,在把country变成默认参数后,我同时把它的位置移到了最后面,为什么呢?

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author: antcolonies
 4 
 5 def stu_register(name, age, country='CN', course):
 6     print("----注册学生信息------")
 7     print("姓名:", name)
 8     print("age:", age)
 9     print("国籍:", country)
10     print("课程:", course)
11 
12 
13 # stu_register("王山炮", 22, "python_devops")
14 # stu_register("张叫春", 21, "linux")
15 stu_register("刘老根", 25, "Japan", "linux")
16 
17 '''
18     def stu_register(name, age, country='CN', course):
19                     ^
20 SyntaxError: non-default argument follows default argument
21 '''
default_var_error

关键参数

正常情况下,给函数传参数要按顺序,不想按顺序就可以用关键参数,只需指定参数名即可,但记住一个要求就是,关键参数必须放在位置参数之后。

stu_register(age=22,name='alex',course="python"):

非固定参数

若你的函数在定义时不确定用户想传入多少个参数,就可以使用非固定参数。

def stu_register(name,age,*args):           # *args 会把多传入的参数变成一个元组形式
    print(name,age,args)
 
stu_register("Alex",22)
# 输出
# Alex 22 ()                #后面这个()就是args,只是因为没传值,所以为空
 
stu_register("Jack",32,"CN","Python")
# 输出
# Jack 32 ('CN', 'Python')

还可以有一个**kwargs:

def stu_register(name,age,*args,**kwargs):     # *kwargs 会把多传入的参数变成一个dict形式
    print(name,age,args,kwargs)
 
stu_register("Alex",22)
# 输出
# Alex 22 () {}        #  后面这个{}就是kwargs,只是因为没传值,所以为空
 
stu_register("Jack",32,"CN","Python",sex="Male",province="ShanDong")
# 输出
# Jack 32 ('CN', 'Python') {'province': 'ShanDong', 'sex': 'Male'}
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author: antcolonies
 4 
 5 
 6 '''
 7 def test(x,y):
 8     print(x)
 9     print(y)
10 
11 
12 test(1,2)        # 位置参数,与形参一一对应
13 1
14 2
15 
16 test(y=2,x=1)    # 关键参数,与形参顺序无关
17 1
18 2
19 
20 test(x=2,3)        # 关键参数不能放于位置参数前
21 SyntaxError: non-keyword arg after keyword arg
22 
23 test(3,x=2)
24 TypeError: test() got multiple values for argument 'x'
25 
26 test(3,y=2)
27 3
28 2
29 
30 '''
31 
32 
33 def test(x,y,z):
34     print(x)
35     print(y)
36     print(z)
37 
38 # test(y=2,x=1,z=3)
39 # 1
40 # 2
41 # 3
42 
43 # test(3,x=1,z=2)
44 # TypeError: test() got multiple values for argument 'x'
45 
46 # test(3,y=1,z=2)
47 # 3
48 # 1
49 # 2
positional & keyword argument
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author: antcolonies
 4 
 5 '''
 6 def test(x, y):
 7     print(x)
 8     print(y)
 9 
10 test(1)
11 TypeError: test() missing 1 required positional argument: 'y'
12 
13 test(1,2,3)
14 TypeError: test() takes 2 positional arguments but 3 were given
15 '''
16 
17 # def test(x, y=3):    # y = 3 为默认参数
18 #     print(x)
19 #     print(y)
20 
21 # test(1)
22 # 1
23 # 3
24 
25 # test(1,10)
26 # 1
27 # 10
28 
29 # 默认参数特点:函数调用时,默认参数非必传
30 
31 
32 # def test(x=4, y):    # SyntaxError: non-default argument follows default argument
33 #     print(x)
34 #     print(y)
35 
36 
37 
38 def test(x,y,z=8):
39     print(x)
40     print(y)
41     print(z)
42 
43 # test(3)
44 # TypeError: test() missing 1 required positional argument: 'y'
45 
46 # test(2,4)
47 # 2
48 # 4
49 # 8
50 
51 # test(2,4,10)
52 # 2
53 # 4
54 # 10
55 
56 # test(2,z=4,y=10)
57 # 2
58 # 10
59 # 4
default argument
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author: antcolonies
 4 
 5 '''
 6 # *args: 接收n个位置参数,转换成元组形式
 7 def test(*args):      # 传递不固定参数
 8     print(args)
 9 
10 test(1,2,3,4,5,10)    # (1, 2, 3, 4, 5, 10)
11 test(*[1,2,4,5])      # args = tuple([1,2,4,5])     (1, 2, 4, 5)
12 
13 
14 def test1(x,*args):
15     print(x)              # 1
16     print(args)           # (2, 4, 6, 7, 89, 10)
17 
18 test1(1,2,4,6,7,89,10)
19 '''
20 
21 '''
22 # **kwargs:接收n个关键字参数转换成字典的方式
23 def test2(**kwargs):
24     print(kwargs)
25     print(kwargs['name'])
26     print(kwargs['age'])
27     print(kwargs['gender'])
28 
29 test2(name='alex',age=8,gender='F')    # 关键字参数 {'gender': 'F', 'age': 8, 'name': 'alex'}
30 test2(**{'name':'alex','age':8,'gender':'F'})       # {'age': 8, 'name': 'alex'}
31 '''
32 
33 '''
34 def test3(name,**kwargs):
35     print(name)
36     print(kwargs)
37 
38 # test3('alex','xxxxx')
39 # TypeError: test3() takes 1 positional argument but 2 were given
40 
41 # test3('alex',age=18,gender='F')
42 # alex
43 # {'age': 18, 'gender': 'F'}
44 
45 # test3('alex')
46 # 'alex'
47 # {}
48 '''
49 
50 '''
51 def test4(name,**kwargs,age=18):    SyntaxError: invalid syntax
52     print(name)
53     print(age)
54     print(kwargs)
55 '''
56 
57 '''
58 def test5(name,age=18,**kwargs):
59     print(name)
60     print(age)
61     print(kwargs)
62 
63 # test5('alex',gender='F',hobby='tesla',age=3)
64 # alex
65 # 3
66 # {'gender': 'F', 'hobby': 'tesla'}
67 
68 # test5('alex',34,gender='F',hobby='tesla',age=3)
69 # TypeError: test5() got multiple values for argument 'age'
70 '''
71 
72 def test6(name,age=18,*args,**kwargs):
73     print(name)
74     print(age)
75     print(args)
76     print(kwargs)
77     logger('TEST4')
78 
79 def logger(source):
80     print('from %s' %source)
81 
82 test6('alex',34,gender='F',hobby='tesla')
83 
84 # alex
85 # 34
86 # ()
87 # {'gender': 'F', 'hobby': 'tesla'}
88 # from TEST4
*args & **kwargs

全局与局部变量

在子程序中定义的变量称为局部变量,在程序的一开始(一级结构)定义的变量称为全局变量。
全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author: antcolonies
 4 
 5 '''
 6 school = 'Fire'                         # 全局变量
 7 
 8 def change_name(name):
 9     # global school                     # 修改全局变量
10     print('before changing ', name)
11     name = 'Alex Li'                    # 局部变量
12     school = 'Ted'
13     print('after changing ', name)
14 
15 name = 'alex'
16 change_name(name)
17 print(school)
18 print(name)
19 
20 # before changing  alex
21 # after changing  Alex Li
22 # Fire
23 # alex
24 '''
25 
26 '''
27 def change_name_1():
28     global name            坚决不能在函数内修改全局变量,容易发生异常,不利于维护
29     name = 'alex'
30 
31 change_name_1()
32 print(name)              # alex
33 '''
34 
35 name = ['Ted','Shooter','Kung']
36 def change_name(name):
37     name[0] = 'Alex Li'      # 引用关系,类似于C语言中的通过函数指针修改源数据
38     print(name)
39 
40 change_name(name)
41 print(name)
42 
43 # ['Alex Li', 'Shooter', 'Kung']
44 # ['Alex Li', 'Shooter', 'Kung']
local & global variate
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author: antcolonies
 4 
 5 def gandpa():
 6     x = 'gandapa'
 7     def dad():
 8         # x = 'dady'
 9         def son():
10            # x = 'sons'
11             print('x = ',x)
12         return son()
13     return dad()
14 
15 gandpa()
arg_overwrite

相关文章:

  • 2022-01-14
  • 2021-06-05
  • 2021-08-09
  • 2021-09-25
  • 2021-12-19
  • 2021-04-04
猜你喜欢
  • 2021-09-02
  • 2021-10-29
  • 2021-09-10
  • 2021-10-11
  • 2021-12-30
  • 2021-07-18
  • 2021-08-03
相关资源
相似解决方案