函数

作者: szn好色仙人 | 来源:发表于2018-04-02 21:20 被阅读0次

函数基础

  • def语句是一个可执行语句,当他运行时,他创建一个新的函数对象并将其赋值给一个变量名。一个def可以出现在任一语句可以出现的地方,并没有什么特别
>>> if True:
    def Fun():
        print('True')
else:
    def Fun():
        print('False')

        
>>> Fun()
True
  • 函数允许任意的属性附加到记录信息以供使用
>>> def Fun() : pass

>>> 'Test' in dir(Fun)
False
>>> Fun.Test = 'Hello Python'
>>> 'Test' in dir(Fun)
True
>>> Fun.Test
'Hello Python'

作用域

  • 当在函数中使用未认证的变量名时,python会搜索四个作用域:本地作用域,之后是上一层def或lambda的本地作用域,之后是全局作用域,最后是内置作用域
  • 内置作用域仅仅是一个名为__builtin__的标准库模块
>>> import builtins
>>> dir(builtins)

['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '_', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']

  • global是一个命令空间声明,告诉python生成一个或多个全局变量名
>>> v = 0
>>> def Fun():
    global v, v1
    v, v1 = "ab"

    
>>> print(v)
0
>>> print(v1)
Traceback (most recent call last):
  File "<pyshell#39>", line 1, in <module>
    print(v1)
NameError: name 'v1' is not defined
>>> Fun()
>>> print(v, v1)
a b
  • 函数能够记住嵌套作用域的变量值,即使那个作用域已经不存在了。若lambda或def在函数中定义,嵌套在一个循环内,并且嵌套的函数引用了一个上层作用域的变量,该变量被循环改变,所有在这个循环内中产生的函数将具有相同的值,这个值是最后一次循环完成时,被引用变量的值
>>> def Fun():
    value = 1
    def FunTest():
        print(value)
    return FunTest

>>> pFunTest = Fun()
>>> pFunTest()
1

>>> def Fun():
    v = []
    for i in range(0, 5):
        v.append(lambda : print(i))
    return v

>>> v1 = Fun()
>>> for i in range(0, 5):
    v1[i]()

    
4
4
4
4
4
  • 默认情况下,当一个函数嵌套在另一个函数中时,嵌套的函数可以引用嵌套的外层def作用域中定义的任何名称,但是不能修改他们。
  • nonlocal声明了将要在一个嵌套的def中修改的名称,此名称不能是全局模块作用域中的,在声明nonlocal时,他必须已存在在该嵌套函数的作用域中。
>>> def F1():
    v1 = 1
    def F2():
        v1 += 1
        print(v1)
    F2()

    
>>> F1()
Traceback (most recent call last):
  File "<pyshell#241>", line 1, in <module>
    F1()
  File "<pyshell#240>", line 6, in F1
    F2()
  File "<pyshell#240>", line 4, in F2
    v1 += 1
UnboundLocalError: local variable 'v1' referenced before assignment
>>> def F1():
    v1 = 1
    def F2():
        nonlocal v1
        v1 += 1
        print(v1)
    F2()

    
>>> F1()
2

>>> def F1():
    v = 1
    def F2():
        def F3():
            nonlocal v
            v += 1
            print(v)
        F3()
    F2()

    
>>> F1()
2

参数

  • 函数参数传递:不可变参数类似C通过值进行传递,可变对象类似C通过指针进行传递

  • 在函数调用中,参数必须以此顺序出现:任何位置参数,后接任何关键字参数和*sequence形式的组合,后跟**dict形式(关键字参数可能会包含在**dict中)

  • 在函数的头部,参数必须以此顺序出现:任何一般参数,后接任何默认参数,如果有的话后接*name(或者python3.0中的*),后面接任何name或name = value 的keyword-only参数,后接**name的形式

  • 利用*和**收集参数

>>> def Fun(*a, **b): print(a, b)

>>> Fun(1, 2, 3, x = 1, y = 2, 'c' = 3)
SyntaxError: keyword can't be an expression
>>> Fun(1, 2, 3, x = 1, y = 2, c = 3)
(1, 2, 3) {'y': 2, 'c': 3, 'x': 1}
  • 解包参数
>>> def Fun(a, b, c, d) : print(a, b, c, d)

>>> Fun(*"abcd")
a b c d
>>> Fun(**{'a':1, 'b':2, 'c':3, 'd':4})
1 2 3 4


>>> def Fun(**a) : print(a)

>>> Fun(**{'a':1, 'b':2, 'c':3, 'd':4})
{'a': 1, 'c': 3, 'd': 4, 'b': 2}


>>> def Fun(a, b = 1, **c):print(a, b, c)

>>> Fun(1, x = 1, y = 2, b = 3)
1 3 {'y': 2, 'x': 1}
  • 强制按照关键字传递参数:在参数列表使用*
>>> def Fun(a, *b, c = 1) : print(a, b, c)

>>> Fun(1, 2)
1 (2,) 1
>>> def Fun(a, *, b = 0, c = 1) : print(a, b, c)

>>> Fun(1)
1 0 1
>>> Fun(1, 2)
Traceback (most recent call last):
  File "<pyshell#358>", line 1, in <module>
    Fun(1, 2)
TypeError: Fun() takes 1 positional argument but 2 were given

函数的高级话题

  • 函数注解
>>> def Fun(a:'A', b:'B' = 1, c:'Test' = [1]) -> int:
    print(a, b, c)

    
>>> Fun(1, 2)
1 2 [1]
>>> Fun.__annotations__
{'b': 'B', 'c': 'Test', 'return': <class 'int'>, 'a': 'A'}
  • lambda表达式只能封装有限的逻辑,甚至连一般的if都不能包含
lambda arg0, arg1...:expression

>>> f = lambda a, b, c : a + b + c
>>> print(f(*"abc"))
abc

>>> f = lambda x : print('True') if x else print('False')
>>> f(0)
False
>>> f(1)
True
>>> f = lambda x : if x : print(x)
SyntaxError: invalid syntax
  • map filter reduce
>>> list(map(lambda x : x * 2, "abc"))
['aa', 'bb', 'cc']
>>> list(map(pow, [1, 2 ,3], [1, 2, 3]))
[1, 4, 27]

>>> list(filter(lambda x : x > 0, [0, 1, 2, -1]))
[1, 2]

>>> from functools import reduce
>>> reduce(lambda x, y : x + y, [1, 2, 3])
6

迭代和解析第二部分

  • 列表解析在一个序列的值上应用任意一个表达式,将其结果收集到一个新的列表中并返回
>>> [ord(x) for x in "szn"]
[115, 122, 110]

>>> [x * 2 + y * 2 for x in "abc" if x == "a" for y in "123" if y == '1' or y == "2"]
['aa11', 'aa22']
  • 生成器函数和常规函数之间的主要不同之处在于,生成器yields一个值,而不是返回一个值。yield语句挂起该函数并向调用者发送回一个值,但是保留足够的状态使得函数能够从他离开的地方继续。当调用时,生成器函数返回一个迭代器对象,该对象支持__next__
>>> def Fun():
    for i in range(0, 5):
        print('Fun:', i)
        yield i

        
>>> Fun()
<generator object Fun at 0x00000000036DFAF8>
>>> list(Fun())
Fun: 0
Fun: 1
Fun: 2
Fun: 3
Fun: 4
[0, 1, 2, 3, 4]
  • send()方法生成一系列结果的下一个元素,这一点类似于next(),但send还提供了一种调用者与生成器之间通信的方法
>>> def Fun():
    for i in range(0, 5):
        x = yield i
        print(x)

        
>>> G = Fun()
>>> G.send(1024)
Traceback (most recent call last):
  File "<pyshell#46>", line 1, in <module>
    G.send(1024)
TypeError: can't send non-None value to a just-started generator
>>> next(G)
0
>>> G.send(1024)
1024
1
>>> G.send('s')
s
2
>>> next(G)
None
3
>>> next(G)
None
4
>>> next(G)
None
  • 生成器表达式语法上类似于一般的列表解析,但他是括在圆括号中
  • 集合解析{f(x) for x in s}等同于set(f(x) for x in s)
  • 字典解析{x:f(x) for x in items}等同于dict((x, f(x)) for x in items)
>>> [x * 2 for x in "szn"]
['ss', 'zz', 'nn']
>>> (x * 2 for x in "szn")
<generator object <genexpr> at 0x00000000036E6EE8>
>>> list((x * 2 for x in "szn"))
['ss', 'zz', 'nn']

>>> {x * 2 for x in "szn"}
{'zz', 'nn', 'ss'}
>>> {x : x * 2 for x in "szn"}
{'s': 'ss', 'z': 'zz', 'n': 'nn'}
  • 生成器函数和生成器表达式自身都是迭代器,并由此只支持一次活跃迭代,我们无法有在结果集中位于不同位置的多个迭代。
>>> def Fun():
    for x in "szn":
        yield x

        
>>> G0, G1 = Fun(), Fun()
>>> iter(G) is G
True
>>> it0, it1 = iter(G0), iter(G0)
>>> next(it0)
's'
>>> next(it1)
'z'
>>> next(G1)
's'
>>> G0 is G1
False
  • 计时
>>> import time
>>> time.clock()
9.330551584887492e-07

>>> import time
>>> def Fun():
    nT0 = time.clock()
    time.sleep(0.1)
    return time.clock() - nT0

>>> Fun()
0.09960021696645072
  • 本地变量是静态检测的
>>> x = 'a'
>>> def Fun():
    print(x)
    x = 1

    
>>> Fun()
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    Fun()
  File "<pyshell#4>", line 2, in Fun
    print(x)
UnboundLocalError: local variable 'x' referenced before assignment

产生上述问题的原因在于被赋值的变量名在函数内部被当做本地变量来对待,而不是仅仅在赋值之后的语句中才被当做本地变量

  • 默认参数是在def语句运行时评估并保存的,而不是在函数调用时
>>> def Fun(x = []):
    x.append(1)
    print(x)


>>> Fun()
[1]
>>> Fun()
[1, 1]
>>> Fun([2])
[2, 1]
>>> Fun()
[1, 1, 1]

相关文章

  • Excel(三)

    AND函数 OR函数 NOT函数 IF函数 频率分析函数FREQUENCY

  • if、else if、for、while、repeat函数

    ①if函数 ②else if函数 ③for函数 ④while函数 ⑤repeat函数

  • strsplit、mapply、paste、match函数

    strsplit函数 mapply函数 strsplit函数 mapply函数 paste函数 match函数 第...

  • Oracle中常用函数(SQL)

    Oracle函授有以下几个分类:数字函数、字符函数、日期函数、转换函数、集合函数、分析函数 数字函数: 字符函数:...

  • MySQL函数

    字符函数 数字运算函数 比较运算符和函数 日期时间函数 信息函数 聚合函数 加密函数 流程函数

  • BI-SQL丨AND & OR & IN

    AND函数 & OR函数 & IN函数 AND函数、OR函数和IN函数都可以理解是WHERE函数的补充,当然也可以...

  • Python之函数

    课程大纲 函数定义 函数的参数 函数的返回值 高阶函数 函数作用域 递归函数 匿名函数 内置函数 函数式编程 将函...

  • 函数基本知识

    函数 函数的定义: def 函数名() 函数的调用:函数名() #不能将函数调用放在函数定义上方 函数的文档注...

  • 积分表——不定期更新

    基本初等函数包括: 常函数: 幂函数 指数函数 对数函数 三角函数 反三角函数 I、反函数Ⅱ、复合函数:初等函数(...

  • MySQL基本使用

    函数 常用函数 数学函数 字符串函数 日期函数

网友评论

      本文标题:函数

      本文链接:https://www.haomeiwen.com/subject/xqqfhftx.html