通常我们定义一个函数, 然后调用该函数时, 函数相关的代码才开始执行. 可是很多人并不知道, 当我们定义函数时, 一些代码就开始执行了. 今天就来说说函数这个不为人知的一面.
先看一段代码:
- def do_something(opt: print('参数 opt'), arg=print('参数 arg')) -> print('函数的返回值'):
- print("do something runing")
- if __name__ == '__main__':
- pass
上面的代码我们定义来一个函数, 但是并没有调用它, 那么它会输出信息吗?
会的, 参数里无论是类型提示部分, 还是默认赋值部分, 还是返回值的类型提示, 里面的语句都会被执行, 结果如下:
这个做法我自己是很少见的. 把 print 函数换成打开文件, 连接数据库之类的操作, 也都会被执行.
不过通常情况下, 参数都是不可变类型, 如果传入可变类型, 可能每次的函数调用, 其结果都会被改变, 例如:
- def do_something(opt: print("参数 opt"), arg=[]) -> print("函数的返回值"):
- print("do something runing")
- print(f"{arg = }")
- arg.append(0)
- if __name__ == "__main__":
- do_something(opt=1)
- do_something(opt=1)
运行结果如下:
可以发现, 调用两次函数 do_something, 虽然并没有传入 arg 参数, arg 的值已经发送了变化. 如果不注意这点, 可能会有 bug 发生. 在 Pythcarm 中, 会警告我们 arg 是可变对象:
如果要获取函数的类型提示, 默认值, 可以这样:
- def do_something(opt: 1, arg=2) -> 3:
- print("do something runing")
- print(f"{arg = }")
- arg.append(0)
- if __name__ == "__main__":
- print(f"{do_something.__annotations__ = }")
- print(f"{do_something.__defaults__ = }")
- #do_something.__annotations__ = {'opt': 1, 'return': 3}
- #do_something.__defaults__ = (2,)
来源: http://developer.51cto.com/art/202111/689308.htm