Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 www.99精品视频在线播放,国内精品久久久久影院6,国产精品日韩欧美久久综合

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          PyScript:讓Python在HTML中運行

          家好,我是DD,已經是封閉在家的第51天了!

          最近一直在更新Java新特性(https://www.didispace.com/java-features/)和IDEA Tips(https://www.didispace.com/idea-tips/)兩個原創專欄,其他方向內容的動態關注少了。昨天天晚上刷推的時候,瞄到了這個神奇的東西,覺得挺cool的,拿出來分享下:

          相信你看到圖,不用我說,你也猜到是啥了吧?html里可以跑python代碼了

          看到好多Python公眾號已經開始猛吹未來了,但乍看怎么覺得有點像JSP?或者一些模版引擎?是進步還是倒退呢?與其瞎想,不如仔細看看這個東東的能力吧!

          根據官方介紹,這個名為PyScript的框架,其核心目標是為開發者提供在標準HTML中嵌入Python代碼的能力,使用 Python調用JavaScript函數庫,并以此實現利用Python創建Web應用的功能。

          看到介紹里提到了調用JavaScript函數庫的能力,看來跟JSP或者模版引擎還是有區別的。

          PyScript 快速體驗

          官方給了一個例子,可以幫助我們觀的感受這個開發框架的能力,不妨跟著DD看看,它能做啥吧!

          第一個案例,hello world

          代碼很簡單,就下面這幾行。你只需要創建一個html文件,然后復制進去就可以了。

          <html>
            <head>
              <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
              <script defer src="https://pyscript.net/alpha/pyscript.js"></script>
            </head>
            <body> 
              <py-script> 
                  print('Hello, World!') 
              </py-script> 
            </body>
          </html>
          

          保存好之后,在瀏覽器里打開就能看到這樣的頁面了:

          回頭再看看這個html里的內容,三個核心內容:

          • 引入pyscript的樣式文件:<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
          • 引入pyscript的腳本文件:<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
          • <py-script>標簽中寫具體的python代碼來輸出Hello World

          如果你懶得自己敲代碼的話,本文的兩個案例代碼我打包放在公眾號了,需要的朋友可以關注公眾號“程序猿DD”,回復:pyscript 獲取。

          第二個案例,數據定義 + 數據展示

          先創建一個data.py文件,然后加入前面的代碼。功能很簡單,就是隨機生成(x,y)的坐標

          import numpy as np
          
          def make_x_and_y(n):
              x = np.random.randn(n)
              y = np.random.randn(n)
              return x, y
          

          再創建一個html文件,加入下面的代碼

          <html>
              <head>
                <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
                <script defer src="https://pyscript.net/alpha/pyscript.js"></script>
                <py-env>
                  - numpy
                  - matplotlib
                  - paths:
                    - /data.py
                </py-env>
              </head>
          
            <body>
              <h1>Let's plot random numbers</h1>
              <div id="plot"></div>
              <py-script output="plot">
              import matplotlib.pyplot as plt
              from data import make_x_and_y
          
              x, y = make_x_and_y(n=1000)
          
              fig, ax = plt.subplots()
              ax.scatter(x, y)
              fig
              </py-script>
            </body>
          </html>
          

          這里就稍微復雜一些了,除了hello world中的幾個要點外,這里還有這幾個要關注的地方:

          • <py-env>標簽:這里聲明要引入的包和要引入的文件(上面創建的data.py
          • <py-script output="plot">:這里定義了要在<div id="plot"></div>中輸出的內容,可以看到這里的邏輯都是用python寫的

          這個頁面的執行效果是這樣的:

          是不是很神奇呢?整個過程中都沒有大家熟悉的cs、js內容,就完成了這樣一個圖的頁面實現。

          小結

          最后,談談在整個嘗試過程中,給我的幾個感受:

          1. 開發體驗上高度統一,對于python開發者來說,開發Web應用的門檻可以更低了
          2. 感覺性能上似乎有所不足,幾個復雜的案例執行有點慢,開始以為是部分國外cdn的緣故,后來移到本地后,還是慢。這部分可能還需要進一步優化。

          這個開發框架目前還只是alpha版本,未來一定還會有更多特性與優化出來,總體上我覺得這個框架還是非常cool的,尤其對于剛學會Python,或者只會Python,但又想快速開發Web應用的小伙伴來說,可能將會是個不錯的選擇,那你覺得這個框架如何?未來會不會火?留言區聊聊吧!

          avaScript 和 Python 是世界上最流行和最常用的兩種語言。JavaScript 是前端和后端 Web 開發不可或缺的一部分。Python 更適合后端和快速應用程序開發。

          兩者各有所長,可以通過從 Python 代碼中運行 JavaScript 代碼來強強聯合,達到兩全其美。

          JavaScript

          JavaScript 是一種用于 Web 開發的腳本語言??梢允褂?JavaScript 向網頁添加行為和功能。是一種解釋性語言,這意味著代碼實時運行,而無需編譯器將其轉換為機器代碼。

          JavaScrip 語法特征:

          代碼塊:JavaScript 使用大括號 {} 定義;

          變量:使用 var 關鍵字定義變量。語法: var variable_name = value;

          常量:使用 const 關鍵字定義常量。語法:constant_name = value;

          輸入/輸出:使用 window.prompt() 在 JavaScript 中獲取輸入,并使用 console.log() 在控制臺上顯示輸出。

          Python

          Python 是一種高級編程語言,在后端開發、人工智能和數據科學中得到了廣泛應用。Python 也是一種釋型語言。

          Python 語法特征:

          代碼塊:Python 使用縮進來定義;

          變量: variable_name = value;

          常量:Python 并不真正支持常量,但約定成俗規定大寫變量視為常量,例如 CONSTANT_NAME;

          輸入/輸出:使用 input() 獲取輸入,并使用 print()顯示輸出。

          js2Py 模塊

          Js2Py 是一個 JavaScript 到 Python 的翻譯組件,要使用此模塊,請打開終端并執行安裝:

          pip install js2py

          Js2Py 自動將任何有效的 JavaScript 轉換為 Python,而無需使用任何依賴項??梢詫⒋蟛糠?JavaScript 代碼轉換為 Python 語言。

          在 Python 中運行 JavaScript 代碼的示例

          1.我們從經典的“Hello World”開始。

          import js2py
          js2py.eval_js('console.log("Hello World!")')

          將 JavaScript 代碼作為參數傳遞給 eval_js() 以對其進行轉換。在 Python 的輸出終端上,顯示“Hello World!”。

          2.兩個數字相加

          在 Python 中使用 JavaScript 執行兩個數字相加的方法。

          import js2py
          js_add = '''function add(a, b){return a + b;}'''
          add = js2py.eval_js(js_add)
          print(add(3, 7))

          使用 JavaScript 聲明一個函數,并將其存儲在字符串中。使用函數 eval_js() 以將其轉換為 Python 等效函數。通過函數調用兩個數字作為參數來顯示結果。

          3.將整個 JavaScript 文件轉換為 Python 文件

          有兩種簡單的方法可以將JavaScript文件轉換為Python文件。

          (1) 使用run_file()函數直接執行 JavaScript 文件。

          import js2py
          eval_result, example = js2py.run_file('example.js')

          (2)轉換整個JavaScript文件為Python文件。

          import js2py
          js2py.translate_file('example.js', 'example.py')

          Python 在web 開發方面主要用于后端編碼,但也可以探索一些工具在前端嘗試它。

          ?

          文章創作不易,如果您喜歡這篇文章,請關注、點贊并分享給朋友。如有意見和建議,請在評論中反饋!

          ?

          先要明白的是,javascript和python都是解釋型語言,它們的運行是需要具體的runtime的。

          • Python: 我們最常安裝的Python其實是cpython,就是基于C來運行的。除此之外還有像pypy這樣的自己寫了解釋器的,transcrypt這種轉成js之后再利用js的runtime的?;旧?,不使用cpython作為python的runtime的最大問題就是通過pypi安裝的那些外來包,甚至有一些cpython自己的原生包(像 collections 這種)都用不了。
          • JavaScript: 常見的運行引擎有google的V8,Mozilla的SpiderMonkey等等,這些引擎會把JavaScript代碼轉換成機器碼執行?;谶@些基礎的運行引擎,我們可以開發支持JS的瀏覽器(比如Chrome的JS運行引擎就是V8);也可以開發功能更多的JS運行環境,比如Node.js,相當于我們不需要一個瀏覽器,也可以跑JS代碼。有了Node.js,JS包管理也變得方便許多,如果我們想把開發好的Node.js包再給瀏覽器用,就需要把基于Node.js的源代碼編譯成瀏覽器支持的JS代碼。

          在本文敘述中,假定:

          • 主語言: 最終的主程序所用的語言
          • 副語言: 不是主語言的另一種語言

          例如,python調用js,python就是主語言,js是副語言

          TL; DR

          適用于:

          1. python和javascript的runtime(基本特指cpython[不是cython!]和Node.js)都裝好了
          2. 副語言用了一些復雜的包(例如python用了numpy、javascript用了一點Node.js的C++擴展等)
          3. 對運行效率有要求的話:
          4. python與javascript之間的交互不能太多,傳遞的對象不要太大、太復雜,最好都是可序列化的對象
          5. javascript占的比重不過小。否則,python調js的話,啟動Node.js子進程比實際跑程序還慢;js調python的話,因為js跑得快,要花很多時間在等python上。
          6. 因為IPC大概率會用線程同步輸入輸出,主語言少整啥多進程多、線程之類的并發編程

          有庫!有庫!有庫!

          python調javascript

          • JSPyBridge : pip install javascript優點:作者還在維護,回issue和更新蠻快的。支持比較新的python和node版本,安裝簡單基本支持互調用,包括綁定或者傳回調函數之類的。缺點 :沒有合理的銷毀機制, import javascript 即視作連接JS端,會初始化所有要用的線程多線程。如果python主程序想重啟對JS的連接,或者主程序用了多進程,想在每個進程都連接一次JS,都很難做到,會容易出錯。
          • PyExecJS : pip install PyExecJS ,比較老的技術文章都推的這個包優點: 支持除了Node.js以外的runtime,例如PhantomJS之類的缺點: End of Life,作者停止維護了

          javascript調python

          (因為與我的項目需求不太符合,所以了解的不太多)

          • JSPyBridge : npm i pythonia
          • node-python-bridge : npm install python-bridge
          • python-shell : npm install python-shell

          原理

          首先,該方法的前提是兩種語言都要有安裝好的runtime,且能通過命令行調用runtime運行文件或一串字符腳本。例如,裝好cpython后我們可以通過 python a.py 來運行python程序,裝好Node.js之后我們可以通過 node a.js 或者 node -e "some script" 等來運行JS程序。

          當然,最簡單的情況下,如果我們只需要調用一次副語言,也沒有啥交互(或者最多只有一次交互),那直接找個方法調用CLI就OK了。把給副語言的輸入用stdin或者命令行參數傳遞,讀取命令的輸出當作副語言的輸出。

          例如,python可以用 subprocess.Popensubprocess.call , subprocess.check_output 或者 os.system 之類的,Node.js可以用 child_process 里的方法, exec 或者 fork 之類的。 需要注意的是,如果需要引用其他包,Node.js需要注意在 node_modules 所在的目錄下運行指令,python需要注意設置好PYTHONPATH環境變量。

          # Need to set the working directory to the directory where `node_modules` resides if necessary
          >>> import subprocess
          >>> a, b = 1, 2
          >>> print(subprocess.check_output(["node", "-e", f"console.log({a}+)"]))
          b'3\n'
          >>> print(subprocess.check_output(["node", "-e", f"console.log({a}+)"]).decode('utf-8'))
          3
          // Need to set PYTHONPATH in advance if necessary
          const a = 1;
          const b = 2;
          const { execSync } = require("child_process");
          console.log(execSync(`python -c "print(${a}+$)"`));
          //<Buffer 33 0a>
          console.log(execSync(`python -c "print(${a}+$)"`).toString());
          //3
          //

          如果有復雜的交互,要傳遞復雜的對象,有的倒還可以序列化,有的根本不能序列化,咋辦?

          這基本要利用 進程間通信(IPC) ,通常情況下是用 管道(Pipe) 。在 stdinstdoutstderr 三者之中至少挑一個建立管道。

          假設我用 stdin 從python向js傳數據,用 stderr 接收數據,模式大約會是這樣的:

          (以下偽代碼僅為示意,沒有嚴格測試過,實際使用建議直接用庫)

          1. 新建一個副語言(假設為JS)文件 python-bridge.js :該文件不斷讀取 stdin 并根據發來的信息不同,進行不同的處理;同時如果需要打印信息或者傳遞object給主語言,將它們適當序列化后寫入 stdout 或者 stderr 。process.stdin.on('data', data => { data.split('\n').forEach(line => { // Deal with each line // write message process.stdout.write(message + "\n"); // deliver object, "$j2p" can be any prefix predefined and agreed upon with the Python side // just to tell python side that this is an object needs parsing process.stderr.write("$j2p sendObj "+JSON.stringify(obj)+"\n); }); } process.on('exit', () => { console.debug('** Node exiting'); });
          2. 在python中,用Popen異步打開一個子進程,并將子進程的之中的至少一個,用管道連接。大概類似于:cmd = ["node", "--trace-uncaught", f"{os.path.dirname(__file__)}/python-bridge.js"] kwargs = dict( stdin=subprocess.PIPE, stdout=sys.stdout, stderr=subprocess.PIPE, ) if os.name == 'nt': kwargs['creationflags'] = subprocess.CREATE_NO_WINDOW subproc = subprocess.Popen(cmd, **kwargs)
          3. 在需要調用JS,或者需要給JS傳遞數據的時候,往 subproc 寫入序列化好的信息,寫入后需要 flush ,不然可能會先寫入緩沖區:subproc.stdin.write(f"$p2j call funcName {json.dumps([arg1, arg2])}".encode()) subproc.stdin.flush() # write immediately, not writing to the buffer of the stream
          4. 對管道化的 stdout / stderr ,新建一個線程,專門負責讀取傳來的數據并進行處理。是對象的重新轉換成對象,是普通信息的直接打印回主進程的 stderr 或者 stdout 。def read_stderr(): while subproc.poll() is None: # when the subprocess is still alive, keep reading line = self.subproc.stderr.readline().decode('utf-8') if line.startswith('$j2p'): # receive special information _, cmd, line = line.split(' ', maxsplit=2) if cmd == 'sendObj': # For example, received an object obj = json.loads(line) else: # otherwise, write to stderr as it is sys.stderr.write(line) stderr_thread = threading.Thread(target=read_stderr, args=(), daemon=True) stderr_thread.start()這里由于我們的 stdout 沒有建立管道,所以node那邊往 stdout 里打印的東西會直接打印到python的 sys.stdout 里,不用自己處理。
          5. 由于線程是異步進行的,什么時候知道一個函數返回的對象到了呢?答案是用線程同步手段,信號量(Semaphore)、條件(Condition),事件(Event)等等,都可以。以 python的條件 為例:func_name_cv = threading.Condition() # use a flag and a result object in case some function has no result func_name_result_returned = False func_name_result = None def func_name_wrapper(arg1, arg2): # send arguments subproc.stdin.write(f"$p2j call funcName {json.dumps([arg1, arg2])}".encode()) subproc.stdin.flush() # wait for the result with func_name_cv: if not func_name_result_returned: func_name_cv.wait(timeout=10000) # when result finally returned, reset the flag func_name_result_returned = False return func_name_result同時,需要在讀stderr的線程 read_stderr 里解除對這個返回值的阻塞。需要注意的是,如果JS端因為意外而退出了, subproc 也會死掉, 這時候也要記得取消主線程中的阻塞 。def read_stderr(): while subproc.poll() is None: # when the subprocess is still alive, keep reading # Deal with a line line = self.subproc.stderr.readline().decode('utf-8') if line.startswith('$j2p'): # receive special information _, cmd, line = line.split(' ', maxsplit=2) if cmd == 'sendObj': # acquire lock here to ensure the editing of func_name_result is mutex with func_name_cv: # For example, received an object func_name_result = json.loads(line) func_name_result_returned = True # unblock func_name_wrapper when receiving the result func_name_cv.notify() else: # otherwise, write to stderr as it is sys.stderr.write(line) # If subproc is terminated (mainly due to error), still need to unblock func_name_wrapper func_name_cv.notify()當然這是比較簡單的版本,由于對JS的調用基本都是線性的,所以可以知道只要得到一個object的返回,那就一定是 func_name_wrapper 對應的結果。如果函數多起來的話,情況會更復雜。
          6. 如果想 取消對JS的連接 ,首先應該先關閉子進程,然后等待讀 stdout / stderr 的線程自己自然退出,最后 一定不要忘記關閉管道 。并且 這三步的順序不能換 ,如果先關了管道,讀線程會因為 stdout / stderr 已經關了而出錯。subproc.terminate() stderr_thread.join() subproc.stdin.close() subproc.stderr.close()

          如果是通過這種原理javascript調用python,方法也差不多,javascript方是Node.js的話,用的是 child_process 里的指令。

          優點

          1. 只需要正常裝好兩方的runtime就能實現交互,運行環境相對比較好配。
          2. 只要python方和javascript方在各自的runtime里正常運行沒問題,那么連上之后運行也基本不會有問題。(除非涉及并發)
          3. 對兩種語言的所有可用的擴展包基本都能支持。

          缺點

          1. 當python與JavaScript交互頻繁,且交互的信息都很大的時候,可能會很影響程序效率。因為僅僅通過最多3個管道混合處理普通要打印的信息、python與js交互的對象、函數調用等,通信開銷很大。
          2. 要另起一個子進程運行副語言的runtime,會花一定時間和空間開銷。

          主站蜘蛛池模板: 日韩精品一区二区三区在线观看 | 不卡一区二区在线| 精品无码一区二区三区在线 | 日韩在线观看一区二区三区| 日本高清一区二区三区| 日韩一区二区视频在线观看| 久久综合亚洲色一区二区三区| 亚洲一区二区三区久久| 国产成人精品一区二三区熟女| 亚洲AⅤ无码一区二区三区在线 | 亚洲高清美女一区二区三区| 激情内射亚洲一区二区三区| 亚洲中文字幕久久久一区| 好看的电影网站亚洲一区| 亚洲日韩精品一区二区三区 | 日本一区二区视频| 亚洲A∨无码一区二区三区| 国产伦精品一区二区三区| 国产精品一区二区三区免费| 精品国产香蕉伊思人在线在线亚洲一区二区 | 丰满岳妇乱一区二区三区| 国产精品一区二区无线| 搜日本一区二区三区免费高清视频| 无码精品人妻一区二区三区AV| 又紧又大又爽精品一区二区| 亚洲免费一区二区| 无码人妻精品一区二区| 日韩av无码一区二区三区| 中文字幕无线码一区二区| 中文字幕在线不卡一区二区| 一区二区三区中文字幕| 久久国产免费一区| 国产一区二区三区播放心情潘金莲| 怡红院一区二区在线观看| 无码精品蜜桃一区二区三区WW| 国产区精品一区二区不卡中文| 2021国产精品一区二区在线| 国产视频一区二区在线观看| 久久精品综合一区二区三区| 亚洲日本一区二区| 亚洲AV无码一区二区三区鸳鸯影院|