python 返回值和作用域


# 函数返回值
# return [1, 3, 5] 返回一个列表
# return 1, 3, 5 看似返回一个值,其实是被隐式的封装成一个元组
# x, y, z, = XX() 用来接收返回值

# 函数嵌套 - 引出作用域的概念
def outer():
def inner():
print('inner')
print('outer')
inner()

# 变量在函数外部
x = 100
def show(): # pass
print(x)
show()

# x = 100
# def show(): # fail(local variable 'x' referenced before assignment)
# x += 1
# print(x)
# show()

# 全局作用域(global - 可以在函数外部定义),局部作用域(local - 函数内)
# 注意赋值即定义的概念
x = 100 # 可以在函数外部定义赋值
def foo():
global x # 全局作用域
x += 1
print(x)
foo()

def foo():
global x # 全局作用域
x = 200 # 可以在函数内部定义赋值
x += 1
print(x)
foo()

# global不要使用,可以通过参数来传递*

# 自由变量:没在本地作用域中定义的变量,如:嵌套函数中外层函数的变量对于内层函数来说就是自由变量
# 闭包:在嵌套函数中,内层函数应用了外层函数的自由变量,对于内层函数来说就叫闭包*
def counter():
c = [0]
def inner():
c[0] += 1 # 对外部变量进行改变,Python2只能这么写
return c[0]
return inner

foo = counter()
print(foo())
c = 100
print(foo())

# nonlocal:将变量标记为上级的局部作用域(Python3)
def counter():
count = 0
def inner():
nonlocal count # 上级的局部作用域
count += 1
return count
return inner # 返回内层函数
# return inner() # 返回内层函数结果

foo = counter()
print(foo())
print(foo())

# 默认值的作用域
def foo(xyz=[]):
xyz.append(10)
print(xyz)

foo() # result: [10]
foo() # result: [10, 10]
# 为什么第二次打印[10, 10]?
# 因为函数也是对象,python把函数的默认值放在了属性中
# 这个属性就伴随着这个函数对象的整个生命周期。即foo.__defaults__属性

def foo(xyz=[], u='abc', z=123):
xyz.append(1)
return xyz

print(foo(), id(foo)) # [1] 44516624。id(foo)表示去foo函数对象的地址
print(foo.__defaults__) # ([1], 'abc', 123)
print(foo(), id(foo)) # [1, 1] 44516624
print(foo.__defaults__) # ([1, 1], 'abc', 123) 元组中的列表是可变类型,可以修改,但不代编元组可变*

# foo.__defaults__属性会将形参的缺省值放入到一个元组中*
def foo(w, u='abc', z=123):
u = 'ccc'
z = 789
print(w, u, z)

print(foo.__defaults__) # ('abc', 123)
foo('test') # test ccc 789
print(foo.__defaults__) # ('abc', 123)

# 形参默认值处理:影子拷贝,默认值安全*
def foo(lst=[], u='abc', z=123):
lst = lst[:] # 影子拷贝(浅拷贝),没有改变形参默认值
lst.append(1)
print(lst)

print('------------------')
foo()
print(foo.__defaults__)
foo()
print(foo.__defaults__)
foo([10])
print(foo.__defaults__)
foo([10, 5])
print(foo.__defaults__)

# 形参默认值处理:默认值为None,对None进行判断**
def foo(lst=None, u='abc', z=123):
if lst is None:
lst = []
lst.append(1)
print(lst)

print('------------------')
foo()
print(foo.__defaults__)
foo()
print(foo.__defaults__)
foo([10])
print(foo.__defaults__)
foo([10, 5])
print(foo.__defaults__)
print('------------------')
 
posted on 2018-08-29 12:56  栗子测试  阅读(396)  评论(0编辑  收藏  举报