代码改变世界

python笔记五之函数

2018-04-24 17:26  等待燃亮  阅读(377)  评论(0编辑  收藏  举报

一、函数是什么?

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

二、使用函数的好处:

1、简化代码
2、提高代码的复用性
3、代码可扩展

三、python中函数的定义:

定义函数使用def关键字,后面是函数名,函数名不能重复

def sayHello():#函数名
    print('hello')#函数体
sayHello()#调用函数

运行结果为:

hello

函数不调用不执行

四、函数的参数

函数在调用的时候,可以传入参数,有形参和实参

形参:

形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。

实参:

实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。函数调用结束返回主调用函数后则不能再使用该形参变量。

def calc(a,b):#a,b 形参,形式参数
    res=a*b
    print('%s * %s = %s'%(a,b,res))
calc(7,8)#实参,实际参数,必填

简单点说,形参就是函数接收的参数,是函数定义时传的参数;而实参就是你实际传入的参数,是调用函数时进行运算用的。

函数的四种形参类型:

位置参数:

位置参数,字面意思也就是按照参数的位置来进行传参,比如说上面的calc函数,a和b就是位置参数,位置参数是必传的,

有几个位置参数在调用的时候就要传几个,否则就会报错了,那如果有多个位置参数的话,记不住哪个位置传哪个了怎么办,可以使用位置参数的名字来指定调用

比如说上面的那个calc函数也可以使用calc(b=1,a=2)这样来调用,这种调用方式叫做关键字传参

默认参数:

默认参数就是在定义形参的时候,给函数默认赋一个值,比如说数据库的端口这样的,默认给它一个值,这样就算你在调用的时候没传入这个参数,它也是有值的

so,默认参数不是必填的,如果给默认参数传值的话,它就会使用你传入的值。如果使用默认值参数的话,必须放在位置参数后面定义。

def conn_mysql(user,passwd,port=3306):#定义一个连接mysql的方法,虽然这个方法并没有连接mysql,我只是举个默认值参数的例子,port就是一个默认值参数
                print(user,passwd,port)
           coon_mysql('root','123456')#没指定默认值
           coon_mysql('root','123456',port=3307)#指定默认值参数的值

非固定参数:

上面的两种位置参数和默认参数都是参数个数是固定的,如果说我一个函数,参数不是固定的,我也不知道以后这个函数会扩展成啥样,可能参数越来越多,这个时候如果再用固定的参数,那后面程序就不好扩展了,这时候就可以用非固定参数了,非固定参数有两种,一种是可变参数,一种是关键字参数。

可变参数:

可变参数用*来接收,后面想传多少个参数就传多少个,如果位置参数、默认值参数、可变参数一起使用的的话,可变参数必须在位置参数和默认值参数后面。可变参数也是非必传的。

def syz(*args):#参数数量不固定,非必填,把传过来的数据转换成元组
    print(args)
syz('niuhanyang','2423',2322)
syz('ls','sdf')
syz()

运行结果分别为:

('niuhanyang', '2423', 2322)
('ls', 'sdf')
()

关键字参数:

关键字参数使用**来接收,后面的参数也是不固定的,想写多少个写多少个,当然也可以和上面的几种一起来使用,如果要一起使用的话,关键字参数必须在最后面。

使用关键字参数的话,调用的时候必须使用关键字传参。关键字参数也是非必传的

def syz2(time,**kwargs):#关键字参数
    print(time,kwargs)
syz2('2018')
syz2('2018',name='nhy',addr='huilongguan')
syz2('2018',name='nhy')
syz2('2018','nhy')#报错,原因是:**kwargs是一个关键字参数,以字典形式存储,K-V必须成对出现

运行结果如下:

2018 {}
2018 {'addr': 'huilongguan', 'name': 'nhy'}
2018 {'name': 'nhy'}

Traceback (most recent call last):
  File "E:/code/syz-code/day5/函数不固定参数.py", line 12, in <module>
    syz2('2018','nhy')#报错,原因是:**kwargs是一个关键字参数,以字典形式存储,K-V必须成对出现
TypeError: syz2() takes 1 positional argument but 2 were given

五、函数的返回值

每个函数都有返回值,如果没有在函数里面指定返回值的话,在python里面函数执行完之后,默认会返回一个None,函数也可以有多个返回值,如果有多个返回值的话,会把返回值都放到一个元组中,返回的是一个元组。

为什么要有返回值呢,是因为在这个函数操作完之后,它的结果在后面的程序里面需要用到。

函数中的返回值使用return,函数在遇到return就立即结束。

def haha():
    for i in range(5):
        print(i)
        if i ==3:
            return  #只写一个return,就返回None
res=haha()#定义一个变量,用来接收函数的返回值
print(res)#不光会打印返回值,还会打印函数执行过程中的输出值

haha()#只打印函数执行过程中的输出值,不打印return的值

运行结果:

0
1
2
3
None


0
1
2
3


def calc(x,y):#这个就是定义了一个有返回值的函数
                c = x*y
                return c,x,y
            res = calc(5,6)#把函数的返回结果赋值给res
            print(res)

六、局部变量和全局变量

局部变量意思就是在局部生效的,出了这个变量的作用域,这个变量就失效了,比如上面的c就是一个局部变量,出了这个函数之后,就没有c这个值了

全局变量的意思就是在整个程序里面都生效的,在程序最前面定义的都是全局变量,全局变量如果要在函数中修改的话,需要加global关键字声明,如果是list、字典和集合的话,则不需要加global关键字,直接就可以修改。

name='xiehong'#全局变量 :公共的变量,大家都可以用
def sayName():
    global name#如果要修改全局变量的值 ,需要用global声明一下,你修改值是全局变量
    name='liuwei'
    print('name1',name)
sayName()
print('name2',name)
#全局变量要少用,1、大家都可以修改,不安全
#2、一直占用内存

运行结果:

name1 liuwei
name2 liuwei

 七、常用内置函数


id() #看内存地址
type() #看数据类型
print() #打印
input() #输入
list() #转list
set()# 转集合
str()#转字符串
dict()#转字典
int()#转int
float()#转float类型
len()#取长度

print(all([1,2,3,4]))#判断可迭代的对象里面的值是否都为真
print(any([0,1,2,3,4]))#判断可迭代的对象里面的值是否有一个为真
print(bin(10))#十进制转二进制
print(bin(10)).replace('0b','')#十进制转二进制时前面会加'0b',如果要使用二进制值可使用replace替换掉
print(bool('s'))#把一个对象转换成布尔类型
print(chr(10))#打印数字对应的ascii
print(ord('b'))#打印字符串对应的ascii码
print(dir(1))#  **打印传入对象的可调用方法,常用内置函数
print(exec('def a():pass'))#执行python代码
eval()#执行python代码,只能执行简单的一些代码
print(filter(lambda x:x>5,[12,3,12,2,1,2,35]))#把后面的迭代对象根据前面的方法筛选
print(map(lambda x:x>5,[1,2,3,4,5,6]))
print(max(111,12))#取最大值
print(min(111,12))#取最小值
print(round(11.11,2))#取几位小数
print(sorted([2,31,34,6,1,23,4]))#排序

八、json模块

JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。JSON的数据格式其实就是python里面的字典格式,里面可以包含方括号括起来的数组,也就是python里面的列表。

  Json   模块提供了四个方法: dumps、dump、loads、load。

1. dumps 和 dump:
 dumps和dump   序列化方法
       dumps只完成了序列化为str,
       dump必须传文件描述符,将序列化的str保存到文件中
>>> import json
>>> json.dumps([])    # dumps可以格式化所有的基本数据类型为字符串
'[]'
>>> json.dumps(1)    # 数字
'1'
>>> json.dumps('1')   # 字符串
'"1"'
>>> dict = {"name":"Tom", "age":23}  
>>> json.dumps(dict)     # 字典
'{"name": "Tom", "age": 23}'
import json
a = {"name":"Tom", "age":23} with open("test.json", "w", encoding='utf-8') as f: # indent 超级好用,格式化保存字典,默认为None,小于0为零个空格 f.write(json.dumps(a, indent=4)) # json.dump(a,f,indent=4) # 和上面的效果一样

运行结果

{
    "age": 23,
    "name": "Tom"
}

2. loads 和 load 

loads和load  反序列化方法

       loads 只完成了反序列化,
       load 只接收文件描述符,完成了读取文件和反序列化
>>> json.loads('{"name":"Tom", "age":23}')
{'age': 23, 'name': 'Tom'}
import json
with open("test.json", "r", encoding='utf-8') as f:
    aa = json.loads(f.read())
    f.seek(0)
    bb = json.load(f)    # 与 json.loads(f.read())
print(aa)
print(bb)

# 输出:
{'name': 'Tom', 'age': 23}
{'name': 'Tom', 'age': 23}