从0.1开始学Python——[13]


文档字符串,它的作用是对函数功能用法等进行说明,对于一些非内置函数,自己定义的函数,如果你希望别人能知道或者看懂它,那你就可以对这些函数编写文档字符串,编写后别人就可以用help(函数对象)函数查看函数的说明,注意,括号里输入的是函数对象, 不带括号

添加文档字符串

在函数里面直接写字符串就行,为了可以跨行写,可以使用三个单引号
另外,可以在形参位置设置数据类型说明和默认值设置,甚至可以用->符号设置返回值类型。但是注意,除了默认值,其他的都是说明,不是强制命令,也就是说你可以输入说明之外的数据类型,但是因为定义函数的人做的这个函数的功能等原因,有可能输入别的数据类型会运行不了。

def van(a:str,b:int=1)->int:
    '''
    函数有啥用,
    参数
    默认值
    '''
    print('♂')

help(van)
Help on function van in module __main__:

van(a: '123456789', b: int = 1) -> int
    函数有啥用,
    参数
    默认值

作用域部分的补充

域(scope),作用域就是变量生效的区域,即产生作用的区域。

def slm():
    a = 20
    print(a)
    
slm()
print(a)
20
Traceback (most recent call last):
  File "D:/4classcode/4classcode/lianxi.py", line 413, in <module>
    print(a)
NameError: name 'a' is not defined

上面这样,a在函数内部定义,结果就是函数外部无法生效,所以print(a)报错。

b = 23
def slm():
    a = 20
    print(a)
    print(b)
slm()
20
23

但是这样,函数外部定义的b则在函数内部还是可以生效,print(b)不会报错。这就说明变量的作用域是有大小之分或者说包含关系的。Python里面一共两种主要作用域:全局作用域函数作用域
全局作用域在程序开始执行的时候就生效了,直到程序执行结束才会消失或说失效,函数之外的地方都是全局作用域。全局作用域创建的变量就叫全局变量,可以在任意位置(包括函数内部)被访问。
函数作用域则在函数调用时创建,函数调用结束时失效。每调用一次函数,就产生一次函数作用域,就是说可以产生很多次函数作用域。显然函数作用域内创建的变量叫作局部变量,只能在函数内被访问,也就是说函数作用域是被包含在全局作用域里面的。
当出现函数嵌套的时候,注意,无论怎么嵌套,都是在最外层函数的内部,所以嵌套在里层的可以访问外层函数的变量,因为越往外变量作用域越大,包含里面的作用域。而一旦涉及了这个函数里面的函数的变量,就不能使用了。

def dick():
    s = 233
    def dick1():
        print(s)
    dick1()
dick()
233

所以这样的不会报错。

def dick():
    s = 233
    def dick1():
        print(s)
        b = 332
    print(b)
    dick1()
dick()
NameError: name 'b' is not defined

而这样就会报错。
当不同的同名局部变量出现在不同层的函数中时,会优先在当前作用域寻找这个变量。没有这个变量才依次往上一级寻找。

def dick():
    s = 233
    def dick1():
        s = 332
        print(s)
    dick1()
dick()
332

使用s的命令在dick1()函数里面,这样就优先找本层函数里面的s,也就是332。如果外层外层全找完直到全局作用域,还没有,就报错。
前面讲到,全局变量可以在任意位置(包括函数内部)被访问,但是举的例子里面函数内并没有同名的变量出现。而局部变量访问是优先在当前作用域寻找这个变量,所以,当出现不同值但同名变量分别在全局和函数内时,会优先使用函数内的局部变量,这个时候想优先用全局变量的时候,就需要用到global关键字

s = 123
print(s)
def dick():
    s = 332
dick()
print(s)
123
123

本来只是优先找到内部的s = 332执行,所以不会影响全局变量。

s = 123
print(s)
def dick():

    global s
    s = 332
dick()
print(s)
123
332

可以看到,使用global定义为全局变量并执行函数之后,全局变量s被改变了。

命名空间部分的补充

命名空间(namespace)是存储变量的位置。每一个作用域对应一个命名空间。保存全局变量的叫全局命名空间,保存局部变量的叫函数命名空间。命名空间的本质是用于存储变量的字典

获取命名空间

locals()函数用来获取当前作用域的命名空间,也就是说在全局用就返回全局命名空间,在函数里面就返回函数命名空间。返回值就是一个字典,可以使用字典操作的命令。

s = 123
print(s)
def dick():

    global s
    s = 332
dick()
print(s)
u = locals()
print(u)
print(u['s'])
123
332
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000196BB66FA08>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/4classcode/4classcode/lianxi.py', '__cached__': None, 'time': <built-in function time>, 'time_ns': <built-in function time_ns>, 'clock': <built-in function clock>, 'sleep': <built-in function sleep>, 'gmtime': <built-in function gmtime>, 'localtime': <built-in function localtime>, 'asctime': <built-in function asctime>, 'ctime': <built-in function ctime>, 'mktime': <built-in function mktime>, 'strftime': <built-in function strftime>, 'strptime': <built-in function strptime>, 'monotonic': <built-in function monotonic>, 'monotonic_ns': <built-in function monotonic_ns>, 'process_time': <built-in function process_time>, 'process_time_ns': <built-in function process_time_ns>, 'thread_time': <built-in function thread_time>, 'thread_time_ns': <built-in function thread_time_ns>, 'perf_counter': <built-in function perf_counter>, 'perf_counter_ns': <built-in function perf_counter_ns>, 'get_clock_info': <built-in function get_clock_info>, 'timezone': -28800, 'altzone': -32400, 'daylight': 0, 'tzname': ('中国标准时间', '中国夏令时'), 'struct_time': <class 'time.struct_time'>, 'str': '123456789', 's': 332, 'dick': <function dick at 0x00000196BB6C6B88>, 'u': {...}}
332

因此字典添加项的操作同样可以添加全局变量,不过不常用。
在函数里面使用locals()自然就是获取函数命名空间,如果函数内部没有局部变量,如下面例子,只有全局变量,那么命名空间就是空字典

def dick():
    global s
    s = 332
    u = locals()
    print(u)
dick()
{}

而有局部变量的话,就返回包含这些信息的字典。

def dick():
    s = 332
    u = locals()
    print(u)
dick()
{'s': 332}

注意,从外部访问不了内部,但是内部能访问外部,作用域是这样,命名空间也是这样。globals()函数可以获取全局命名空间,在函数里面使用,并进行字典找项的操作也可以打开全局变量。和global 变量 的方法效果差不多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值