名称空间,存放名字的地方,准确的说名称空间是存放名字与变量值绑定关系的地方
内置名称空间:python自带的名字,在python解释器启动时产生,存放一些python内置的名字
全局名称空间:在执行文件时,存放文件级别定义的名字
局部名称空间:在执行文件的过程中,如果调用了函数,则会产生该函数的名称空间,用来存放该函数内定义的名字,该名字在函数调用时生效,调用结束后失效
加载顺序:内置名称空间------>全局名称空间----->局部名称空间
名字的查找顺序:局部名称空间------>全局名称空间----->内置名称空间
四:作用域,作用的范围
全局作用域:全局存活,全局有效
局部作用域:局部存活,局部有效
名称空间与作用域
#内置名称空间
#全局名称空间
#局部名称空间
import time 这些自带的就是内置名称空间,iport 在定义名字,跟x=1一样,
class Foo:
pass
x=1 顶头写的,没有任何缩进的就是全局名称空间
def funcname():
y=100
print(y)
print(x)
funcname()
# print(y)
#内置名称空间:只要起了解释器都能用,比全局名称空间还高,全局作用域
#全局名称空间:定义好了之后,在任何地方都可以用,全局作用域
#局部名称空间:局部作用域
寻找的顺序,先局部,再全局,再内置
def func2():
print(y)
def foo():
bar()
def bar():
print("a")
foo()
bar()
不会报错,因为我foo定义的时候,bar虽然不存在,但是,我只检查语法,并不执行,
当我回头再来执行,foo的时候,这时候,bar已经定义为全局名称空间,所以不报错
x=1
def func():
print('from func')
x=2
a=1
b=2
print(globals())查看全局作用域
print(locals())查看局部作用,很简单,只有x=2
# a=globals()查看全局作用域,参照为此文件
func()
# b=locals()查看全局作用域,参照为此文件
# print(a == b)
#嵌套调用
# def my_max(x,y):
# res=x if x > y else y
# return res
#
# print(my_max(10,100))
#
# def my_max4(a,b,c,d):
# res1=my_max(a,b)
# res2=my_max(res1,c)
# res3=my_max(res2,d)
# return res3
# print(my_max4(1,20,3,4))
#嵌套定义
x =111111111111111111111111111111111111111111111
def f1():
# x = 1
print('------>f1 ',x)
def f2():
# x=2
print('---->f2 ',x)
def f3():
# x=3
print('-->f3 ',x)
f3()
f2()
f1()
名称空间本身只是个隔离的单位而已,而作用域是寻找一个变量的顺序,是一个动作。
##################################################################################
函数被称为第一类对像
什么叫第一类对像,函数可以被当作数据来传递,有什么特性,x=1, y=x 可以传递,y就拿到了值1
# def foo():
# print('foo')
# print(foo)
#函数可以被赋值
# f=foo
# print(f)
# f()
#把函数当成参数传递
# def bar(func):
# print(func)
# func()
#
# bar(foo)
#把函数当成返回值
# def bar(func):
# print(func)
# return func
#
# f=bar(foo)
# print(f)
# f()
#把函数当做容器类型的元素去用
def add():
print('=============>function add')
def search():
print('=============>function search')
def delete():
print('=============>function delete')
def change():
print('=============>function change')
def tell_msg():
msg='''
search:查询
add:添加
delete:删除
change:修改
create:新建
'''
print(msg)
def create():
print('function ---->create')
cmd_dic={
'search':search,
'add':add,
'delete':delete,
'change':change,
'create':create
}
while True:
tell_msg()
choice=input('please input your choice: ').strip()
# print(cmd_dic[choice])
cmd_dic[choice]()
以上代码代表着一种程序思想,先在开头def各种定义,每个功能定义一个,然后,在下边再进行调用
##########################################################
作用域在你定义的时候,就已经好了,不管你在什么位置调用,用到,就跑到最原始的定义位置去找
# x=100000000000000000
# def f1():
# x=1
# def f2():
# print(x)
# return f2
#
# f=f1()
# print(f)
# x=123123123123123123
# f()
闭包 必须是内部定义的函数,该函数包含对外部作用域而不是全局作用域名字的引用
如上面,以上的f2调用
x=1 # def f1(x): # # x=1000闭包是对外部作用域,而非全局作用域的引用 # def f2(): # print(x) # return f2 # # f=f1(10000000000000) #f---->内部的f2(函数不加()只是一个内存地址,只是一个定义,只检查语法不执行,加上()才开始执行,这里的f,看着好像只有f2其实,还包括x=1000(核心)(不传x值的时候
)传x值,他也是闭包,只不过是从f1传过来的) # x='asdfasdfasdfasdfasdf' # x='asdfasdfasdfasdfasdf' # x='asdfasdfasdfasdfasdf' # x='asdfasdfasdfasdfasdf' # x='asdfasdfasdfasdfasdf' # f() # print(f.__closure__)只要是闭包一定有这个变量 # print(f.__closure__[0].cell_contents) # print(f.__closure__) # print(f.__closure__[0].cell_contents) # print(f.__closure__[1].cell_contents) from urllib.request import urlopen def get(url): return urlopen(url).read() # print(get('http://www.baidu.com')) # print(get('http://www.python.org')) from urllib.request import urlopen def f1(url): def f2(): print(urlopen(url).read()) return f2 python=f1('http://www.python.org') #下载页面+'http://www.python.org'
预习装饰器