学习参考:
https://docs.python.org/3/reference/
https://python3-cookbook.readthedocs.io/zh_CN/latest
python 是一种 dynamically-typed language,以牺牲类型安全性(在 compile time 无法做类型检查,只有在 run time 才能去确定对象的类型)为代价,换来了编码上的灵活性(可以不用声明直接用——duck typing )
当一行代码要使用变量 x
的值时,Python会到所有可用的名字空间去查找变量,按照如下顺序:
x
,Python将使用这个变量,然后停止搜索。x
的变量,函数或类,Python将使用这个变量然后停止搜索。x
是内置函数或变量。Python使用名字空间来记录变量的轨迹。名字空间是一个
字典,它的键就是变量名,字典的值就是那些变量的值。局部名字空间可以通过内置的
locals()
函数来访问。全局(模块级别,包括内置名字空间)名字空间可以通过
globals()
函数来访问。
python中模块的__all__
:__all__
为一元组,每一个元素为一字符串,为该模块中的变量、方法、类,当模块为一单一py文件时可定义于模块内部,当模块为一文件夹时,可定义于*__init__.py*文件中。
__all__
属性,则只有__all__
内指定的属性、方法、类可被导入,若没定义,则导入模块内的所有公有属性,方法和类。from pak import *
的方法无法导入,但当import pak
时,仍可使用pak._func
和pak.__func
直接访问。在python中,类型注解的有意义的价值是:静态分析、类型检查和人类阅读。虽然在技术上可以通过类型注解来实现函数重载,但这不符合python的使用原则。所以在自己对安全性、清晰性和灵活性的权衡下做类型注解即可。
类型别名比较实用:
from typing import TypeAlias
= tuple[tf.Tensor, tf.Tensor]
_LossAndGradient: TypeAlias = Mapping[str, _LossAndGradient] ComplexTFMap: TypeAlias
可以认真学习下这一段,涉及到元类、描述器和函数注解的编程技术的思想:https://python3-cookbook.readthedocs.io/zh_CN/latest/c09/p20_implement_multiple_dispatch_with_function_annotations.html
编程:
https://google.github.io/styleguide/
因为yield实现的生成器是一个暂停&重启的执行模型,所以在python中它可以成为一种协程的实现,逻辑细节如下:
生成器G中temp = yield expression1
这行代码的逻辑是:
next
或send
或throw
或close
的线程称之为这里的调用方)next(G)
或者G.send(expression2)
或者G.throw(Exception1)
或者G.close()
时,所在的线程便会阻塞调用方,然后执行生成器G所在的协程;NOTE:
G.close()
等价于G.throw(GeneratorExit)
。yield from
委托生成器对子生成器做一层包装,代码逻辑更清晰。https://python3-cookbook.readthedocs.io/zh_CN/latest/c12/p12_using_generators_as_alternative_to_threads.html
有待阅读:https://docs.python.org/zh-cn/3/library/asyncio-task.html
= "echo test, test, test, OK!"
cmdline print(os.popen(cmdline).read())