编译型语言和解释型语言
和其他编译型语言类似,要 执行python代码 会经历几个步骤。
分别是这三个步骤:
1. 词法分析
2. 语法解析
3. 编译
解释型语言区别于编译型型语言,他有一个很大的缺点由于不需要事前先编译成机器码,而是在动态执行的时候在解释器运行期间那一条解释一条,这些被解释完成的代码 会在内存中存放 python中称为 code object(代码对象),写python的小伙伴应该经常能看见 个__pycache__ 这个文件夹 里面或有一些 和代码相对应的.pyc相对应的文件。这些就是解释器将内存里的 代码对象保存到 本地磁盘 以便下一次调用是能够复用这些被编译过的代码,加快编译器的执行效率。当我们外部引入一些不需要修改的包,直接使用编译好的代码对象,解释器就能加快速度。当然当我们对代码修改时他会检查 最近修改时间,和pyc生成时间 如果发生改变 那么不会使用原来的pyc,但并不是所有的文件python解释器都认为值得缓存 代码对象.pyc 。另外解释性语言 是没法检查一些例如类型错误 他只能在执行的时候才能发现。
动态类型语言:动态类型语言是指在运行期间才去做数据类型检查的语言,也就是说,在用动态类型的语言编程时,永远也不用给任何变量指定数据类型,该语言会在你第一次赋值给变量时,在内部将数据类型记录下来。Python和Ruby就是一种典型的动态类型语言
静态类型语言:静态类型语言与动态类型语言刚好相反,它的数据类型是在编译其间检查的,也就是说在写程序时要声明所有变量的数据类型,C/C++是静态类型语言的典型代表
2、强类型定义语言和弱类型定义语言
(1)强类型定义语言:强制数据类型定义的语言。也就是说,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了。举个例子:如果你定义了一个整型变量a,那么程序根本不可能将a当作字符串类型处理。强类型定义语言是类型安全的语言。
(2)弱类型定义语言:数据类型可以被忽略的语言。它与强类型定义语言相反, 一个变量可以赋不同数据类型的值。
强类型定义语言在速度上可能略逊色于弱类型定义语言,但是强类型定义语言带来的严谨性能够有效的避免许多错误。另外,“这门语言是不是动态语言”与“这门语言是否类型安全”之间是完全没有联系的!
例如:Python是动态语言,是强类型定义语言(类型安全的语言); JAVA是静态语言,是强类型定义语言(类型安全的语言)。
1、什么是类型安全
类型安全简单来说就是访问可以被授权访问的内存位置,类型安全的代码不会试图访问自己未被授权的内存区域。一方面,类型安全被用来形容编程语言,主要根据这门编程语言是否提供类型安全的保障机制;另一方面,类型安全也可以用来形容程序,根据这个程序是否隐含类型错误。类型安全的语言和程序之前,其实没有必然的联系。类型安全的语言,使用不当,也可能写出来类型不安全的程序;类型不安全的语言,使用得当,也可以写出非常安全的程序。
解释器类型
python解释器 其实和java一样是一个虚拟机,java在执行前会对文件进行编译成字节码,再加进虚拟机。
package core
import (
"fmt"
"testing"
"time"
)
type listx struct {
in string
pc int//指令计数器
}
type what_to_execute struct {
stack *PyStack
instructions []listx
numbers []int//存储数据
names []string
}
func NEwwhat_to_execute() *what_to_execute{
return &what_to_execute{
stack :NewStack(),
}
}
func Newlistx(ins string,num int){
}
func TestAddestx(t *testing.T) {
a := NEwwhat_to_execute()
a.numbers =[]int{7,5,8}
a.names=[]string{"a","b"}
x1 := listx{in:"LOAD_VALUE", pc:0}
x2 := listx{in:"LOAD_VALUE", pc:1}
x3 := listx{in:"ADD_TWO_VALUES",pc:-1}
x4 := listx{in:"LOAD_VALUE", pc:2}
x5 := listx{in:"ADD_TWO_VALUES", pc:-1}
x6 := listx{in:"LOAD_VALUE", pc:1}
x7 := listx{in:"ADD_TWO_VALUES", pc:-1}
x8 := listx{in:"STORE_NAME", pc:0}
//x9 := listx{in:"PRINT_ANSWER", pc:0}
a.instructions = append(a.instructions,x1,x2,x3,x4,x5,x6,x7,x8)
now := time.Now()
for _,val := range a.instructions{
instruction, argument := val.in,val.pc
var args PyValue
if argument == -1{
a.instruction(instruction,nil)
}else{
switch instruction {
case "STORE_NAME":
args = a.names[argument]
case "LOAD_NAME":
args = a.names[argument]
default:
args = a.numbers[argument]
}
a.instruction(instruction,args)
}
fmt.Println("当前python栈状态 :" ,a.stack.environment)
}
spenftime := time.Now().Sub(now)
fmt.Println(spenftime)
}
func (lx *what_to_execute) instruction(fun string,val PyValue) {
switch fun{
case "LOAD_VALUE":lx.stack.push(val)
case "ADD_TWO_VALUES":lx.stack.add()
case "PRINT_ANSWER":lx.stack.print()
case "STORE_NAME":lx.stack.STORE_NAME(val)
case "LOAD_NAME":lx.stack.LOAD_NAME(val)
}
}
仿照500lines 的内容 只是个没写完的小demo。
https://github.com/qiaojinxia/gothon
500lindes Byterun 的中文翻译: https://linux.cn/article-7753-1.html