def qqxing(l = []): # 可变数据类型
    l.append(1)
    print(l)
qqxing()            # [1]
qqxing([])          # [1]
qqxing()            # [1, 1]
qqxing()            # [1, 1, 1]

# 如果默认参数的值是一个可变数据类型,那么每一次调用函数的时候,如果不传值,就公用这个数据类型的资源

def qqxing(l = {}):      # 可变数据类型
    l['k'] = 'v'
    print(l)
qqxing()                # {'k': 'v'}
qqxing({})              # {'k': 'v'}
qqxing()                # {'k': 'v'}
qqxing()                # {'k': 'v'}def qqxing(k, l = {}):      # 可变数据类型
    l[k] = 'v'
    print(l)
qqxing(1)               # {1: 'v'}
qqxing(2)               # {1: 'v', 2: 'v'}
qqxing(3)               # {1: 'v', 2: 'v', 3: 'v'}
qqxing(4)               # {1: 'v', 2: 'v', 3: 'v', 4: 'v'}
# 函数进阶
# a = 1
# def func():
#     print(a)
# func()# def func():     # 报错
#     a = 1
# func()
# print(a)

# 命名空间和作用域

# 命名空间:有三种
# 内置的命名空间 -- python解释器
# 就是python解释器一启动就可以使用的名字,存储在内置命名空间中(比如:print())
# 内置的名字在启动解释器的时候被加载进内存里
# 全局命名空间 -- 我们写的代码,但不是函数中的代码
# 是在程序从上到下被执行的过程中一次加载进内存的
# 放置了我们设置的所有变量名和函数名
# 局部命名空间 -- 函数
# 就是函数内部定义的名字
# 当调用函数的时候才会产生这个名称空间,随着函数执行的结束,这个命名空间就又消失了

# 在局部中,可以使用全局、内置命名空间中的名字
# 在全局中:可以使用内置命名空间中的名字,但是不能用局部中的名字
# 在内置中:不能使用局部和全局的名字的

#-------------------------------------------------------------------------------------#

# 当我们在全局定义了和内置命名空间中相同的名字, 会使用全局的名字
# 在正常情况下(全局没有定义),直接使用内置的名字
# 当我自己有的时候, 就不找上级要了;如果自己没有, 就一直找上一级要.若最后都没有就会报错
# 多个函数应该拥有多个独立的局部名字空间,不互相共享

# def input():
#     print('in input now')
#
# def func():
#     # input = 1
#     print(input)
#     input()
# func()
'''
func --> 函数的内存地址
func() --> 函数名(): 函数的调用
故 --> 函数的内存地址():函数的调用
'''
'''
def func():
    a = 1
def func():
    print(a)


只能从上级找,不能局部命名空间之间找
# 多个函数应该拥有多个独立的局部名字空间,不互相共享
'''

# 作用域:两种
# 全局作用域 --> 作用在全局 -- 内置和全局名字空间中的名字都属于全局作用域 -- globals()
# 局部作用域 --> 作用在局部 -- 函数(局部名字空间中的名字属于局部作用域) -- locals()
'''

对于不可变数据类型,在局部可以查看全局作用域中的变量,但是不能 直接 修改;
如果想要修改,需要在程序中的一开始添加global声明(尽量少使用)
如果在一个局部(函数)内声明了一个global变量,那么这个变量在局部的所有操作将对全局的变量有效
locals() 函数会以字典类型返回*当前位置*的全部局部变量
本地的:locals()放在局部就打印局部的全部变量,放在全局里就是打印全局的全部变量,这时等于

globals()
a = 1
def func():
    a += 1
    print(a)
func()
-------------------------------------------------------------
a = 1
def func():
    global a
    a += 1
    print(a)
func()
'''
#
# a = 1
# b = 2
# def func():
#     x = 'xxx'
#     y = 'yyy'
#     print(locals())
# func()
# print(globals())# globals()永远打印全局的名字
# locals():输出什么  会根据locals所在的位置# def max(a,b):
#     if a > b:
#         return a
#     else:
#         return b
#
# def the_max(x,y,z):         # 函数的嵌套调用
#     c = max(x,y)
#     return max(c,z)
# print(the_max(1,2,3))# 函数的嵌套定义
# 内部函数可以使用外部函数的变量
# nonlocal 只能用于局部变量(对全局无效),找上层中离当前函数最近一层的局部变量(对局部也是对最近的一层有影响)
# 声明了nonlocal的内部函数的变量修改会影响到离当前函数最近一层的局部变量
# a = 5
# def outer():
#     a = 1
#     def inner():
#         b = 2
#         def inner2():
#             # print(a, b)
#             # global a            # 声明一个全局变量(但这个地方的a是局部变量)
#             nonlocal a              # 声明一个上面第一层 局部 变量, 若所有局部变量都没有, 则报错
#             a += 1              #报错, 不可变数据类型的修改
#             print('inner2:', a)
#         inner2()                    # 需要调用
#         print('inner:',a)
#     inner()                     # 需要调用
#     print('outer:', a)
# outer()
# print('**a**:', a) 
def func():
    print(123)
# func()  # 函数名就是内存地址
# func2 = func   # 函数名可以赋值
# func2()
#
# l = [func, func2]   # 函数名可以作为容器类型的元素
# print(l)
# for i in l:
#     i()# def wahaha(f):
#     f()
# wahaha(func)        # 函数名可以作为函数的参数def wahaha(f):
    f()
    return f            # 函数名可以作为函数的返回值
qqxing = wahaha(func)        #qqxing()
# def outer():
#     a = 1
#     def inner():        # inner()是一个闭包
#         print(a)
#     print(inner.__closure__)   # (<cell at 0x0000027BBB57C828: int object at 0x00007FF9F9D7D420>,)
#                                     # cell 说明inner()是闭包
# outer()
# print(outer.__closure__)        # None   说明outer不是闭包# 闭包:嵌套函数,且内部函数调用外部函数的变量
#
# def outer():
#     a = 1
#     def inner():
#         print(a)
#     return inner
# inn = outer()
# inn()import urllib       # 模块
from urllib.request import urlopen
# ret = urlopen('http://www.xiaohua100.cn/guowai/').read()
# print(ret)
# def get_url():
    # ret = urlopen('http://www.xiaohua100.cn/guowai/').read()
    # print(ret)def get_url():
    url = 'http://www.xiaohua100.cn/guowai/'
    def inner():
        res = urlopen(url).read()
        print(res)
    return inner
inn = get_url()
inn()