def fn(xx):        #形参

return xx

print(fn('hello'))    #实参数

callable

return 1

True

In [1]: def f(x,y):

...:     print(x,y)

...:

In [2]: f('a','ccc')

a ccc

In [3]: f(y='python', x='hello')

hello python

In [5]: def f(x,y,z):

...:     print(x,y,z)

In [7]: f(z=None,y=10,x=[1])

[1] 10 None

In [8]: f((1,),z=6,y=4.1)

(1,) 4.1 6

In [13]: f((1,),z=6,1)

File "<ipython-input-13-452adbde2693>", line 1

f((1,),z=6,1)

^

SyntaxError: positional argument follows keyword argument

result = x + y

print(result)

13

#将关键字参数先传进会提示报错

^

SyntaxError: positional argument follows keyword argument

result = x + y

print(result)

127.0.0.1:8080:chaoye/q1w2e3

192.168.0.1:9909:haha/q1w2e3

192.168.0.1:9909:chaoye/thi

*name 可变参数

def fn(*args):

print(type(args))

print(args)

fn(1,2,3,4,88)

<class 'tuple'>

(1, 2, 3, 4, 88)

fn()

<class 'tuple'>        # 可变参数在封装过程中，将其以元组的方式进行传递

()

def fn(*nums):

sum = 0

for x in nums:

sum+=x

print(sum)

fn(10)

10

*传递是一个不可变的类型（元组)

In [5]: def add(*nums):

...:     sum = 0

...:     for x in nums:

...:         sum += x

...:     print(sum)

...:     #retrun sum

...:

In [6]: val = add(3,5,7)

15

In [8]: print(val)

None

In [12]: def add(*nums):

...:     sum = 0

...:     for x in nums:

...:         sum += x

...:     return(sum)

0

Out[14]: 0

**kwargs 可变关键字参数

**kwargs 将传递进来的值封装为字典类型，格式如下：

def showconfig(**name):

print(name)

showconfig(a=5,b=32,hj=90)

{'a': 5, 'b': 32, 'hj': 90}

def showconfig(**kwagrs):

for k,v in kwagrs.items():

print(k,v)

hostname 127.0.0.1

port 8080

passwd 134qwe

for k,v in kwagrs.items():

print('{} = {}'.format(k,v))

showconfig('wangchao','1234',host='127.0.0.1')

wangchao

1234

host = 127.0.0.1

print(args)

for k,v in kwargs.items():

print(k,v)

showconfig('chaoye')

*args 一般需要定义在**kwargs 之前的位置，以复杂度进行排放

print(args)

for k,v in kwargs.items():

print(k,v)

File "E:\python_project\a.py", line 3

^

SyntaxError: invalid syntax

[Finished in 0.1s with exit code 1]

·有位置可变的参数和关键可变的参数，*args和**kwargs

·位置可变参数和关键字可变参数（*args和**kwargs都可以收集若干个实例，位置可变参数(*args)收集实参封装为一个元组，关键字可变参数(**kwargs)则封装为一个字典

·混合使用参数的过程，可变参数要放到参数的列表最后，普通参数需要放到参数列表前，位置参数*args需放置**kwargs关键字参数前

即： 位置参数 --> 关键字参数 -->*args --> **kwargs

def fn(*args,x,y,**kwargs):

print(x)

print(y)

print(args)

print(kwargs)

fn(1,2,3)

TypeError: fn() missing 2 required keyword-only arguments: 'x' and 'y'

fn(3,5,a=1,b='py')

fn(3,5,y=1,x=2,b='python')

2

1

(3, 5)

{'b': 'python'}

keyword-only 关键字参数形参（强制参数）

keyword-only 在python3种加入，如在一个星号形参后，或一个位置可变参数后，则是kw-only参数类型

def fn(*args,x):

print(x)

print(args)

fn(3,5,1,x=9)

args可以手机所有的位置参数，x不能使用关键字参数就不可能拿到实参

*号特殊意义   后期详细看

def fn(*,x,y):

print(x,y)

fn(x=1,y=2)

def fn(z,*,x,y):

print(z)

print(x,y)

fn(9,x=1,y=3)

def fn(*args,x=1):

print(x)

print(args)

print(host,port)

print(user)

print(kwargs)

connect(db='cmdb')

localhost 3306

{'db': 'cmdb'}

connect(host='123',db='cmdb')

123 3306

{'db': 'cmdb'}

print(x+y)

return x+y

print(x+y)

return x+y

t = (3,4)

print(x,y)

t = [1,2]

1 2

t = [1,2,3,4]

TypeError: add() takes 2 positional arguments but 4 were given

1 2

def fn(**kwargs):

for k,v in kwargs.items():

print(k,v)

d = {'a':1,'b':2}

fn(**d)

result = 0

for x in iterable:

result += x

return result

return和print

return的作用是直接出栈，写在return之后会被认为是废语句

print 会作为隐含类型进行转换并输出

return = return None

def showlist():

return [1,2,3]

print(type(showlist()))

showlist返回的为一个值，这里为一个列表，但是列表中是存在元素的

def showlist():

return 1,2,3

print(type(showlist()))

def outer():

def inner():

print('inner')

print('outer')

outer()

inner()

inner()

NameError: name 'inner' is not defined

def fn():

out = 123        #这个变量也算为一个标识符

print('outer')

fn()

x = 50

def show():

print(x)

show()

x = 50

def show():

x += 1

print(x)

show()

x += 1

UnboundLocalError: local variable 'x' referenced before assignment

在整个程序中运行环境都可见

在函数内定义的变量，被称为本地变量，只限局部使用范围，其他范围不可以被调用

def outer1():

o = 65

def inner():

print('inner',o)

print('outer',o)

inner()

outer1()

outer 65

inner 65

def outer2():

o = 65

def inner():

o = 97              #当进入嵌套函数中，o已经被重新定义为一个新的变量

print('inner',o)    #其打印的变量为上行重新定义的值

print('outer',o)

inner()

outer2()

outer 65

inner 97

x = 5

def foo():

y = x + 1

x += 1

print(x)

foo()

y = x + 1

UnboundLocalError: local variable 'x' referenced before assignment

x没有被赋值的空标识符所以都被认为是局部变量

z = 1

def xx():

global z

z += 21

print(z)

xx()

22

x = 5

def foo():

y = x + 1

x += 1

print(x)

foo()

y = x + 1

UnboundLocalError: local variable 'x' referenced before assignment

z = 1

def xx():

global z

z += 21

print('xx_z:',z)

xx()

print('global_z:',z)

xx_z: 22

global_z: 22

def counter():

c = [0]

def inc():

c[0] += 1         #仅仅是对元素在赋值，与赋值变量是两码事

return c[0]

return inc            # 是返回一个标识符（函数的引用），可调用的对象，inc本身就是可调用对象

foo = counter()

print([foo() for _ in range(10)])

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

def counter():

c = [0]

def inner():

c[0] += 1

return c[0]

return inner

foo = counter()

print(type(foo))

<class 'function'>

c = 200

def counter():

c = [0]

def inner():

c[0] += 1

return c[0]

return inner

c = 200

foo = counter()

print(type(foo))

c = 200

print(foo())

print(foo())

<class 'function'>

1

2

c = 200

def counter():

c = [0]

def inner():

c[0] += 1

print(c)

return c[0]

print(c[0])

return inner

foo = counter()

foo()

foo()

[0]

#以下为闭包所产生的值

1

2

3

nonlocal

python3使用了nonlocal方式进行闭包

python2 中和 python3种的闭包对比：

python3

def outer():

count = 0

def inner():

nonlocal count

count += 1

print(count)

return count

return inner

foo = outer()

foo()

foo()

1

2

python2中，仅能对自由变量进行操作

def outer():

c = [0]

def inner():

c[0] += 1

print(c)

return c

return inner

foo = outer()

foo()

foo()

def foo(a=[]):

a.append(100)

print(a)

foo()

[100]

In [2]: foo.__defaults__

Out[2]: ([],)

In [3]: foo()

[1]

In [4]: foo()

[1, 1]

In [10]: foo.__defaults__

Out[10]: ([1, 1],)

In [11]: print(foo(),id(foo))

[1, 1, 1]

None 139733908903048

In [12]: print(foo.__defaults__)

([1, 1, 1],)

In [13]: print(foo(),id(foo))

[1, 1, 1, 1]

None 139733908903048

In [14]: print(foo.__defaults__)

([1, 1, 1, 1],)

In [15]: print(foo(),id(foo))

[1, 1, 1, 1, 1]

None 139733908903048

def foo(a=None):

if a is None:

a = []

a.append(1)

return a

print(foo([1]))

print(foo())

[1, 1]

[1]

1.使用浅拷贝创建一个新的对象，永远不能改变传入的参数

2.通过值判断，灵活的选择串讲或者修改传入的对象

方法很龙火，在很多场景下，函数定义都可以看到使用None，这个不可变的值作为默认值进行传参，

1.del funcname

2.覆盖，查看地址是否一致

3.待到程序结束时