189 8069 5689

38py改变函数参数的值关键字参数和参数默认值函数中可变参

第五课:改变函数参数的值
一个python函数可以有任意多个参数,在一个函数的外部来定义变量,然后把变量作为参数传入到函数内,并且在函数的内部来修改函数的参数值,函数结束之后,这些变量的值在如何变化呢?
给函数传递值有2种:1种是值传递,1种是引用传递 

# 改变函数参数的值
# 值传递(数值、字符串、布尔 这些都是值传递) 在函数的内部修改变量值,不改变原参数定义的参数值,解释为: 这个在函数中不会改变原来定义(函数外部)的值   这是因为函数里面会有一个占的概念,外边的变量的值会复制给 占 里面,对于 函数中的变量来说 并不是指的是同一个变量 在函数里修改的参数的变量的值其实是修改了函数的一个副本,和外边的参数没有直接关系 
# 引用传递(复合类型,列表、字典、以后要讲的对象)  在函数的内部修改变量值,将会改变原参数定义的参数值, 具体的解释为: 这个在函数中会改变原来定义(函数外部)的值 这里的引用和c语言的指针比较类似 
x = 100
s = 'hello world'
def test1(xx,ss):     # 将这2个变量变成参数传给 函数test1 
    xx = 200
    ss = 'I love you.'
test1(x,s)            # 这一步是讲外边的定义的变量传给函数    
print(x, s)             # 结果为  100 hello world 值没有变化 还是和外边定义的变量值是一样的 这是因为 x s 都是值传递 
-------
复杂的类型
numList = [1,2,3,4,5]
numDict = {'a':1, 'b':2, 'c':3}
a = numList
a[1] = 4
print(numList)      # [1, 4, 3, 4, 5]  这一步是将numList的引用复制了一份给了a 那么这样的numList 和 a 他们的引用(指针) 指向同一个地址空间,如果我们修改了a的值numList的值也就被修改了 这里的变量是存储了列表和字典的引用 ;其实光看这个引用的话,其实就是把这个列表和字典的引用传给函数中的值 在函数体内,所用的内存空间和外部的是一样的,所以值就会根据函数体内的值的改变而改变。
def test2(nl,nd):
    nl[2] = 1234
    nd['c'] = 4321
test2(numList, numDict)   # 函数传参 
print(numList)            # [1, 4, 1234, 4, 5]
print(numDict)              # {'a': 1, 'b': 2, 'c': 4321}
# 我们发现这里的输出的值,改变了原先定义的列表和字典 这里叫做 引用传递 

输出的结果为:
100 hello world     // 这个结果和原来定义的没变   
[1, 4, 3, 4, 5]     // 这里类似于 引用 (指针),值是会改变的 
[1, 4, 1234, 4, 5]
{'a': 1, 'b': 2, 'c': 4321}

-------------------------------------------------------------------
第六课:改变函数参数的值(案例)  // 这个例子很牛逼 
在 控制台输入一些数据,以逗号分隔的字符串 , 然后把这些数据转化为字典或者序列 
# 从控制台输入一些数据(以逗号分隔的字符串),然后保存到一个大的字典中     首先先用普通的方法实现,然后将一部分的代码抽象处理,然后再用函数去实现  我们就是用复合类型的数据,将字典传入函数,然后在函数的内部 修改字典的值,当函数结束的时候,保留在函数内部修改的效果 

data = {}                   # 首先定义个字典
data['d'] = {}              # d的放在字典
data['names'] = []          # names放在列表中 
print('请输入字典数据,key和value之间用逗号分隔')    # 从控制台输入 
dictStr = input(':')                            # 从控制台输入
# 比如:我们输入
# a,b,c,d
# {'a':'b','c':'d'}
list = dictStr.split(',')      # 利用逗号进行分割 
keys =[]                            # key 和 value 都取出来, 奇数的Wie  key   偶数为 values 
values =[]
for i in range(len(list)):
    if i % 2 == 0:
        keys.append(list[i])
    else:
        values.append(list[i])
print(keys)                     # ['a', 'b', 'c']
print(values)                       # ['1', '2', '3'] 
for values in zip(keys,values):       #  将第一个列表的第一个元组值转化为 元组 
    print(values)
'''
('a', '1')
('b', '2')
('c', '3')
'''

输出的结果为:
请输入字典数据,key和value之间用逗号分隔
:a,1,b,2,c,3
['a', 'b', 'c']
['1', '2', '3']
('a', '1')
('b', '2')
('c', '3')
----------------------------- 
第二种方法:
data = {}
data['d'] = {}
data['names'] = []
print('请输入字典数据,key和value之间用逗号分隔')
dictStr = input(':')
# a,b,c,d
# {'a':'b','c':'d'}
list = dictStr.split(',')      # 分隔符为 ,
keys =[]
values =[]
for i in range(len(list)):
    if i % 2 == 0:            # 偶数 分割   true为 key    false为 values 
        keys.append(list[i])         
    else:
        values.append(list[i]) 
data['d'].update(dict(zip(keys,values)))       # 这一步的意思是 把元组转化为字典 更新到d这个字典后面  

print('请输入姓名,多个姓名之间用逗号分隔')
nameStr = input(':')
names = nameStr.split(',')
data['names'].extend(names)      # 把另外一个列表追加到一个列表的后面 

print(data)

输出的结果为:
请输入字典数据,key和value之间用逗号分隔
:a,1,b,2,c,3
请输入姓名,多个姓名之间用逗号分隔
:majihui,zhaoshun
{'d': {'a': '1', 'b': '2', 'c': '3'}, 'names': ['majihui', 'zhaoshun']} 

如果我们有多个data这样的字典,难道我们的代码要复制10份吗,下面引入 函数 :我们把代码进行抽象,放在一个函数里面 对重复使用的代码。

第三种方法:函数的方法 
# 从控制台输入一些数据(以逗号分隔的字符串),然后保存到一个大的字典中
#  1.  初始化字典data
#  2.  从控制台输入以逗号分隔的字符串,并将其转换为列表或字典
#  3.  输出字典data

# 1.  初始化字典data
def init(data):
    data['d'] = {}
    data['names'] = []
# 2.  从控制台输入以逗号分隔的字符串,并将其转换为列表或字典
# True:转换为列表,False:转换为字典
def inputListOrDict(flag,msg):
    print(msg)
    inputStr = input(':')
    list = inputStr.split(',')
    # 直接返回列表
    if flag:
        return list
    keys =[]
    values =[]
    result = {}
    for i in range(len(list)):
        if i % 2 == 0:
            keys.append(list[i])
        else:
            values.append(list[i])
    return dict(zip(keys,values))    

#  3.  输出字典data
def outDict(data):
    for key in data.keys():
        print(key, ':', data[key])

// 把上面这3个 函数 封装成一个模块 dataman 我们要维护代码的话,就只需要维护下面这几个 就可以了 
from dataman import *

data1 = {}
data2 = {}
init(data1)
init(data2)

data1['d'].update(inputListOrDict(False, '请输入字典数据'))
data1['names'].extend(inputListOrDict(True, '请输入列表数据'))

data2['d'].update(inputListOrDict(False, '请输入字典数据'))
data2['names'].extend(inputListOrDict(True, '请输入列表数据'))

outDict(data1)
outDict(data2)

--------------------------------------------------------
课程七:函数中关键字参数和参数默认值
# 关键字参数和参数默认值 

# 位置参数    中 形参   值参      

# 混合使用位置参数和关键字参数 需要注意点
# 1. 关键字参数必须跟在位置参数后面
# 2. 同一个形参不能同时使用位置参数和关键字参数赋值

# 函数参数默认值,如果一个参数有默认值,那么该参数后面的所有的参数必须都有默认值,否则会抛出异常
def greet(name, greeting):                  # 函数里面有参数 一个参数叫name  一个参数叫 greeting   这2个叫形参 
    return '问候语:{}  姓名:{}'.format(greeting, name) 

print(greet('李宁', 'Hello'))    #  问候语:Hello  姓名:李宁       这里的 Hello 李宁 就表示的值参
print(greet('Hello', '李宁'))   # 问候语:李宁  姓名:Hello

# 解决参数的调用方式,解决参数的代码的语言 通俗的讲 就是解决调用的参数的时候,能一下子让人看的懂 
# 关键字参数 可以不按照形参的输入顺序   本讲的主要内容  

print(greet(name='李宁',greeting='Hello'))        # 关键字的参数就是形参的名字  在函数的内部和外部都可以使用,内部就是形参 外部就是一个变量 
print(greet(greeting = 'Hello', name='李宁'))

print(greet('Bill', greeting='Hello'))      # 关键字参数和位置参数混合使用   生产上建议用关键字参数,让人一看代码就明白 
# print(greet(name='Mike', 'Hello'))     # 这个会报错 不行 为什么呢?
# 混合使用位置参数和关键字参数 需要注意点
# 1. 关键字参数必须跟在位置参数后面
# 2. 同一个形参不能同时使用位置参数和关键字参数赋值

# print(greet('Bill', name='Hello'))  

def fun(a,b,c = 123,d=4,e=12,f =20,g=40):  # 函数参数默认值,如果一个参数有默认值,那么该参数后面的所有的参数必须都有默认值,否则会抛出异常
    print(a,b,c,d,e,f,g)
fun(1,2,3,4,5)        # 1 2 3 4 5 20 40 

----------------------------------------------------------------------
第八课:函数中可变参数
// 什么是可变参数?
任意传输参数值是可变的,传输的参数的个数是不定的 可变参数的可变是表示参数的个数是可以变化的 
如何在一个函数中,定义可变参数
# 可变参数

# print(1,2,3,4,5,7,'a')
# 可变参数在函数内部的表现形式是一个元组
# 一般情况下,可变参数需要放在普通参数后面
# 如果可变参数后面还有普通参数,如果普通参数没有默认值,为普通参数传值
# 必须要使用关键字参数形式,如果有默认值,可以不传值
def printParams(*params):    # 在函数中定义一个可变参数,需要在 参数的前面加一个* 就成为 可变参数 
    print(params)

printParams("hello", 1,True)        # ('hello', 1, True)  表现形式是一个元组  这里面的参数可以随便的调整,

def printParams1(*params):
    for param in params:                            # 对每一个元组进行了for循环的迭代 
        print('<' + str(param) + '>', end = ' ')   # 需要提前转化为字符串 因为有可以输入的是数值,数值不可以和字符串直接相加 
printParams1('hello',1,2,3,False,40.1)              #  <1> <2> <3>  <40.1>   我们得到了每一个值

print()
def printParams2(value, *params):         # 一般情况下,把可变参数放到 普通参数后面 也有不一般的情况下 后面讲
    print('[' + str(value) + ']')
    for param in params:
        print('<' + str(param) + '>', end = ' ')
printParams2('hello',1,2,3,4)                        
# [hello]
# <1> <2> <3> <4>

#def printParams3(value1, *params, value2 = 20, value3=30):  解决方法1 在定义函数的时候加上默认值 
def printParams3(value1, *params, value2, value3):
    print('[' + str(value1) + ']')
    print('[' + str(value2) + ']')
    print('[' + str(value3) + ']')
    for param in params:
        print('<' + str(param) + '>', end = ' ')
printParams3('hello',1,2,3,4,5,value2 = 100, value3 = 200)       # 解决方法2 在输出的时候,加上关键字参数

--------------------------------------------------------------------
第九课:将序列中的元素值作为函数对应的参数值传递    
# 将序列作为函数的参数值  并不是将一个序列看成一个整体,传入函数的一个参数;而是将这个序列拆开,将每一个序列的元数值作为一个单独的参数传入函数的参数。

def printParams1(s1, s2):
    print(s1, s2)

printParams1("Hello", "World")
strList = ['Hello', 'World'] 
printParams1(*strList)       #  把列表前面加一个*  就会把列表中的参数的值拆开 到函数的每一个参数中   最后的值为: Hello World

def printParams2(*ss):      # 定义成可变参数,也是可以的 
    for s in ss:
        print('<{}>'.format(s), end = ' ')  

printParams2(*strList)        #  
print()
printParams2(*'abcdefg')     #            直接传值 
print()
printParams2(*[1,2,3,4,5,6]) # <1> <2> <3> <4> <5> <6>     他会自动的把列表的值拆开 作为可变参数传入 

def printParams3(**ss):          # 如何我们传入字典呢?   传入字典需要2 个 ** 
    for item in ss.items():     # 这里用 items 方法输入 key value 
        print(item)             # 变量输出 表现形式为 元组 
        print('{} = {}'.format(item[0], item[1]))
dict = {'a':10, 'b':20,'c':30}
printParams3(**dict)                           
printParams3(**{'name':'Bill','age':20})     
'''
a = 10
('b', 20)
b = 20
('c', 30)
c = 30
('name', 'Bill')
name = Bill
('age', 20)
age = 20 
'''

# 这个是不加2个**        和加2个** 是没有本质的区别的   我操 
def printParams4(ss):
    for item in ss.items():
        print(item)
        print('{} = {}'.format(item[0], item[1]))
dict = {'a':10, 'b':20,'c':30}
printParams4(dict)
printParams4({'name':'Bill','age':20})

注意:
为函数传递可变参数值(单星和双星参数)
单星和双星 参数 : 都是作为扩展参数用的  区别是什么呢? 
*a     # 导入元组和列表的
**a    # 导入字典的 

def f1(a1,*a2):
    print(a1)
    print(a2)
f1(1,2,3,4,5)
输出结果
1
(2, 3, 4, 5)

def f2(a1,**a2):
    print(a1)
    print(a2)
f2(1,aaa=111,bbb=222)
输出的结果为:
1
{'aaa': 111, 'bbb': 222}
#就会自动的把后面关键字参数转化为字典输出

本文标题:38py改变函数参数的值关键字参数和参数默认值函数中可变参
标题来源:
http://cdxtjz.com/article/goppdc.html