## 3.Pikascript标准开发流程 本篇文档将会介绍基于PikaScript开发的标准流程,这个标准流程将会涵盖大部分情况下会用到的PikaScript相关技术。 我们依然以keil的仿真工程为例,如果还没有获得仿真工程,请参考[1.三分钟快速上手](1.三分钟快速上手.md) ## (1). 使用已有的PikaScript类包 ### 1) PikaScript类包与包接口 我们打开pikascript文件夹,发现文件夹根目录下除了main.py,还有Device.py,PikaObj.py和PikaStdLib.py,这三个.py文件分别对应三个PikaScript***类包***(class package),简称***包***(package),每个.py文件本身称为***包接口***(package interface)。 ![image](https://user-images.githubusercontent.com/88232613/131083885-a78befe9-7aee-4bae-84cc-86c81eef7622.png) 每一个PikaScript***类包***由***包接口***和***包实现***(package implement)两部分组成。 我们先打开Device.py查看一下内容,在后续的文档中我们会称Device.py为***Device包接口***。 以下就是Device.py的全部内容。 ``` python # Device.py from PikaObj import * class LED(TinyObj): def on(): pass def off(): pass class Uart(TinyObj): def send(data:str): pass def setName(name:str): pass def printName(): pass ``` 可以看到,Device.py中使用pyhon标准语法定义了两个类,分别是`LED`类和`Uart`类,这两个类都继承自```TinyObj```。 LED类中定义了两个方法,分别是`on()`方法和`off()`方法,而`Uart`类则定义了`send(data:str)`方法、`setName(name:str)`方法和`printName()`方法。 可以看到,这些方法都有一个特点,与其说这是方法的***定义***,不如说是方法的***声明***,因为所有的方法实现都pass掉了,都没有写实现。而且方法的入口参数都是带有***类型声明***的。比如`data:str`就表示一个`data`参数,参数类型为`str`即字符串类型。 这是因为这个包的包实现是由C语言编写的,也就是说,PikaScript的所有类包,都是使用python语法编写声明,而使用C语言编写实现。PikaScript的类包开发是一种***面向接口***编程的***混合编程***技术。 然而在使用已有的类包时,是不需要了解包实现的,只需要了解包接口,即可使用这个类包。 ### 2) 导入并调用包 下面我们看一下如何使用这个类包。 我们打开工程中的main.py,见名知意,这个文件是PikaScript的入口文件。 main.py的内容如下 ``` python # main.py from PikaObj import * import Device import PikaStdLib led = Device.LED() uart = Device.Uart() mem = PikaStdLib.MemChecker() print('hello wrold') uart.setName('com1') uart.send('My name is:') uart.printName() print('mem used max:') mem.max() print('mem used now:') mem.now() ``` 导入一个已经编写好的类包是非常简单的,比如导入Device包,只需要`import Device`即可,要注意的是所有的.py文件应当放在pikascript文件架的根目录下。 然后使用Device中的LED类新建对象,只需要写一句`uart = Device.Uart()`即可,这表示新建一个`uart`对象,这个对象的类是Device包中的Uart类。 调用方法则使用`uart.setName('com')`这种形式,这都是Python的标准语法,不需要过多介绍。 在main.py中写好包的调用后,双击rust-msc-v0.5.0.exe即可预编译PikaScript工程,预编译的输出文件在pikascrip-api文件夹内。 ![image](https://user-images.githubusercontent.com/88232613/131095540-46b38726-8fda-4b10-94f1-5af31ae7a792.png) pika预编译器会为导入的包生成.h声明文件和-api.c构造器文件。文件名以包名开头,每个类对应一个.h文件和一个-api.c文件。 ![image](https://user-images.githubusercontent.com/88232613/131096295-8b1b2161-cb59-45e6-92f3-eb2cf79a47f7.png) 而PikaMain-api.c和PikaMain.h则是对应了一个特殊的类,这个类是PikaScript的主类,由main.py编译而成。 ![image](https://user-images.githubusercontent.com/88232613/131096521-569e30a0-876e-4bb5-bfd3-0c01b6b8a38f.png) pikaScript.c和pikaScript.h则是根据main.py编译出的初始化函数,运行初始化函数时,会自动执行启动脚本。 ![image](https://user-images.githubusercontent.com/88232613/131096760-20592a84-bbc1-4b61-a57f-299183983adf.png) 在现在的main.py中,启动脚本是写在最外层的方法调用,也就是: ``` python print('hello wrold') uart.setName('com1') uart.send('My name is:') uart.printName() print('mem used max:') mem.max() print('mem used now:') mem.now() ``` 编译出的pikaScriptInit()初始化函数对应的是: ``` c PikaObj * pikaScriptInit(){ PikaObj * pikaMain = newRootObj("pikaMain", New_PikaMain); obj_run(pikaMain, "print('hello wrold')"); obj_run(pikaMain, "uart.setName('com1')"); obj_run(pikaMain, "uart.send('My name is:')"); obj_run(pikaMain, "uart.printName()"); obj_run(pikaMain, "print('mem used max:')"); obj_run(pikaMain, "mem.max()"); obj_run(pikaMain, "print('mem used now:')"); obj_run(pikaMain, "mem.now()"); return pikaMain; } ``` ## (2) 编写新的类包