@@ -195,6 +195,27 @@ def print_func(args):
195195:::
196196::::
197197
198+ ### 控制台输入示例
199+
200+ ::: warning
201+ 请注意 ` CONSOLE ` 标签中光标闪烁的地方!
202+ 按 ` Enter ` 键,或输入框失去焦点后会自动执行。
203+ :::
204+
205+ :::: preview 控制台输入示例
206+
207+ :::playground#python 控制台输入示例
208+
209+ @file main.py
210+
211+ ``` python
212+ inp = input (' 请输入一些内容:' )
213+ print (' 这是你输入的内容:' , inp)
214+ ```
215+
216+ :::
217+ ::::
218+
198219## 开发背景
199220
200221为了学习 Python (很遗憾没坚持下来。。) 希望能达到能及时看到代码执行结果的目的,希望加人一个 Python Playground。
@@ -305,6 +326,98 @@ api // vercel 要求,必须放到根目录下
305326
306327对策,Vercel 环境中,找不到原来的 session 时就新建一个,其实相当于每次都新建 session,这也导致了部署后,代码提示会相对比较慢。
307328
329+ ## 注意点
330+
331+ 开发中不熟悉 Pyodide, 也不熟悉 MonoEditor, Web Worker 所以遇到了不少问题,这里简单记录一下。
332+
333+ - SharedArrayBuffer is not defined
334+ 在处理 ` stdin ` 中,用到了 SharedArrayBuffer,但是使用上有些限制,需要配置 ` headers ` 。
335+
336+ MDN 文档:[ 安全需求] ( https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements )
337+
338+ 本地开发时,需要在 ` vite.config.ts ` 中配置一下。
339+
340+ ``` ts title="vite.config.ts"
341+ server : {
342+ // SharedArrayBuffer is not defined
343+ headers : {
344+ ' Cross-Origin-Embedder-Policy' : ' require-corp' ,
345+ ' Cross-Origin-Opener-Policy' : ' same-origin' ,
346+ // 'Cross-Origin-Resource-Policy': 'same-site', // 嵌入方式仅在本站内使用
347+ ' Cross-Origin-Resource-Policy' : ' cross-origin' , // 嵌入方式仅在本站内使用
348+ },
349+ },
350+ ```
351+
352+ 服务器端也需要做相应配置。
353+ 由于本人使用 vercel 部署,所以需要配置一下 ` vercel.json ` 。
354+
355+ ``` json title="vercel.json"
356+ {
357+ "headers" : [
358+ {
359+ "source" : " /(.*)" ,
360+ "headers" : [
361+ {
362+ "key" : " Cross-Origin-Embedder-Policy" ,
363+ "value" : " require-corp"
364+ },
365+ {
366+ "key" : " Cross-Origin-Opener-Policy" ,
367+ "value" : " same-origin"
368+ },
369+ {
370+ "key" : " Cross-Origin-Resource-Policy" ,
371+ "value" : " cross-origin"
372+ }
373+ ]
374+ }
375+ ]
376+ }
377+ ```
378+
379+ - ` stdin ` 处理 python ` input `
380+ 在 python 中处理 ` input ` 时用到了两个输入流,一个是用来做控制的,一个是用来处理数据的。
381+ 由于 ` input ` 会有用户交互,所以用到了 ` Atomics.wait ` 来做中断,等待用户输入完后再继续处理。
382+
383+ Pyodide 文档: [ 设置中断] ( https://pyodide.org/en/stable/usage/keyboard-interrupts.html#setting-up-interrupts )
384+
385+ python repl 中有以下代码。
386+
387+ ``` js
388+ inputBuffer = new SharedArrayBuffer (4 )
389+ inputTextBuffer = new SharedArrayBuffer (1024 )
390+
391+ inputView = new Int32Array (inputBuffer)
392+ inputTextView = new Uint8Array (inputTextBuffer)
393+
394+ Atomics .store (inputView, 0 , 0 )
395+ Atomics .wait (inputView, 0 , 0 )
396+ ```
397+
398+ 前台处理中有以下代码。
399+
400+ ``` js
401+ // 返回 Uint8Array
402+ const encoder = new TextEncoder ()
403+ const inputData = encoder .encode (el .value )
404+
405+ const inputTextBuff = new Uint8Array (buff) // buff 是 repl 创建的 SharedArrayBuffer(1024)
406+
407+ // 将用户数据放到 inputTextBuff 中
408+ for (let i = 0 ; i < inputData .length ; i++ ) {
409+ inputTextBuff[i] = inputData[i]
410+ }
411+ inputTextBuff[inputData .length ] = 0
412+
413+ // 使用 Atomics 恢复程序
414+ const inputView = new Int32Array (inputBuff) // inputBuff 是 repl 创建的 SharedArrayBuffer
415+ Atomics .store (inputView, 0 , 1 )
416+ Atomics .notify (inputView, 0 )
417+ ```
418+
419+ repl 和 前台的这两个输入流的类型必须一致。
420+
308421## 类似功能
309422
310423其他网站已提供现成的功能,可以直接使用。本次开发中也借鉴了它们,再次表示感谢。
0 commit comments