在编译语言中,源代码由编译器转换为目标代码,不同的目标文件(如果有多个文件)由链接器链接,并由加载器加载到内存中执行。
如果我有一个使用解释性语言(例如,ruby 或 python)编写的应用程序,并且如果源代码是跨文件拆分的,那么这些文件究竟是什么时候组合在一起的。换句话说,链接何时完成?解释语言是否首先具有链接器和加载器,或者解释器会做所有事情?
我真的对此感到困惑,无法理解它!任何人都可以对此有所了解吗?
在编译语言中,源代码由编译器转换为目标代码,不同的目标文件(如果有多个文件)由链接器链接,并由加载器加载到内存中执行。
如果我有一个使用解释性语言(例如,ruby 或 python)编写的应用程序,并且如果源代码是跨文件拆分的,那么这些文件究竟是什么时候组合在一起的。换句话说,链接何时完成?解释语言是否首先具有链接器和加载器,或者解释器会做所有事情?
我真的对此感到困惑,无法理解它!任何人都可以对此有所了解吗?
解释语言或多或少是称为解释器的可执行文件的大型配置。该可执行文件(例如/usr/bin/python
)是实际运行的程序。然后它读取它应该执行的脚本(例如/home/alfe/bin/factorial.py
)并以最简单的形式逐行执行它。
在该过程中,它可能会遇到对其他文件(其他模块,例如/usr/python/lib/math.py
)的引用,然后它将读取并解释这些文件。
许多此类语言具有内置机制,通过创建它们解释的脚本的字节码版本来减少此过程的开销。因此,很可能有一个文件/usr/python/lib/math.pyc
,解释器在第一次处理后将其放在那里,并且它可以比原始/usr/python/lib/math.py
. 但这并不是解释语言概念的一部分¹。
有时,二进制库是解释语言的一部分;根据解释器的复杂程度,它可以在运行时链接该库,然后使用它。这对于需要高度优化的系统模块和东西来说是最典型的。
但总的来说,可以说根本不会生成二进制机器代码。在编译时没有任何链接。实际上,没有真正的编译时间,即使可以将输入脚本的第一次处理称为编译步骤。
脚注:
¹)解释脚本的概念既不包括“编译”(将源预翻译成更快解释的形式)也不包括通过存储文件等.pyc
文件来“缓存”这种形式。WRT 关于将程序链接和拆分为多个文件或模块的问题,预编译和缓存的这些方面只是加快速度的技术细节。概念本身是:读取一行输入脚本并执行它。然后阅读下一行,依此类推。
好吧,在 Python 中,当解释器找到某种方法或指示时,模块会被加载、执行或解析。没有链接,但当然有加载(当在代码中请求文件时)。
Python 做了一些聪明的事情来提高它的性能。.pyc
它在第一次执行文件时编译为字节码(文件)。这大大提高了下次导入或执行模块时代码的执行。
所以行为或多或少:
这就是该过程的完成方式(非常笼统)。当然,还有优化和缓存来提高性能。
希望这可以帮助!