搜尋
首頁後端開發Python教學Python和JavaScript間交換資料的方法

telepath是一個Django庫,用於在Python和JavaScript之間交換數據,使您可以建立具有豐富客戶端介面的應用程序,同時將業務邏輯保留在伺服器端程式碼中。

它有什麼作用?

它提供了一個將包括Python物件在內的結構化資料打包為JSON可序列化格式的機制。透過向對應的JavaScript實作註冊該機制,可以擴展該機制以支援任何Python類別。然後,打包的資料可以包含在HTTP回應中,並在JavaScript中解壓縮以獲得與原始資料等效的資料結構。

安裝方法

pip install telepath

並將'telepath'新增至專案的INSTALLED_APPS。

簡介

假設我們正在建立一個用於玩跳棋的Django應用程式。我們已經花了數天或數週的時間,建構了遊戲規則的Python實現,並提供了代表當前遊戲狀態和各個部分的類別。但是,我們也希望為播放器提供一個適當且友善的使用者介面,這意味著該是我們編寫JavaScript前端的時候了。我們的UI程式碼不可避免地將擁有自己的對象,這些對象代表不同的角色,鏡像我們正在伺服器上追蹤的資料結構——但我們無法發送Python對象,因此將這些資料傳送到客戶端通常將意味著設計遊戲狀態的JSON表示形式,並在兩端分別設計大量樣式程式碼,遍歷資料結構以在本機物件之間來回轉換。讓我們看看telepath如何簡化這個過程。

一個完整的跳棋遊戲對於本教學來說有點太多了,所以我們只選擇渲染這一步...

在Python環境中,創建一個新的Django專案:

pip install "Django>=3.1,<p>在draughts / settings.py的INSTALLED_APPS清單中加入'games'。 </p><p>為簡單起見,在本範例中,我們將不涉及資料庫,而是將遊戲狀態表示為普通的Python類別而不是Django模型。修改games/views.py,如下所示:</p><pre class="brush:php;toolbar:false">from django.shortcuts import render   class Piece:     def __init__(self, color, position):         self.color = color         self.position = position   class GameState:     def __init__(self, pieces):         self.pieces = pieces      @staticmethod     def new_game():         black_pieces = [             Piece('black', (x, y))             for y in range(0, 3)             for x in range((y + 1) % 2, 8, 2)         ]         white_pieces = [             Piece('white', (x, y))             for y in range(5, 8)             for x in range((y + 1) % 2, 8, 2)         ]         return GameState(black_pieces + white_pieces)   def game(request):     game_state = GameState.new_game()      return render(request, 'game.html', {})

如下所示建立games/templates/game.html:

nbsp;html>               <title>Draughts</title>         <script>             document.addEventListener(&#39;DOMContentLoaded&#39;, event => {                 const gameElement = document.getElementById(&#39;game&#39;);                 gameElement.innerHTML = &#39;TODO: render the board here&#39;             });         </script>                   <h2 id="Draughts">Draughts</h2>         <div>         </div>      

將新視圖新增至draughts/urls.py:

from django.contrib import admin from django.urls import path  from games.views import game  urlpatterns = [     path('', game),     path('admin/', admin.site.urls), ]

現在,使用./manage.py runserver啟動伺服器,並造訪http:// localhost:8000 /。

到目前為止,我們已經創建了一個代表新遊戲的GameState物件——現在是時候引入telepath,以便我們可以將該物件傳輸到客戶端。執行下方指令:

pip install telepath

並將'telepath'加入draughts /  settings.py中的INSTALLED_APPS清單中。現在編輯games/views.py檔案:

import json from django.shortcuts import render from telepath import JSContext  # ...  def game(request):     game_state = GameState.new_game()      js_context = JSContext()     packed_game_state = js_context.pack(game_state)     game_state_json = json.dumps(packed_game_state)      return render(request, 'game.html', {         'game_state_json': game_state_json,     })

這裡JSContext是一個幫助工具,用於管理遊戲狀態物件到我們可以在Javascript中使用的表示形式的轉換。 js_context.pack接受該物件並將其轉換為可以JSON序列化並傳遞到我們的模板的值。但是,現在重新載入頁面失敗,並出現以下形式的錯誤:don't  know how to pack object:

這是因為GameState是Telepath尚不知道如何處理的自訂Python類型。傳遞給pack的任何自訂類型必須連結到對應的JavaScript實作;這是透過定義Adapter物件並將其註冊到telepath來完成的。如下更新game  / views.py:

import json from django.shortcuts import render from telepath import Adapter, JSContext, register  # ...  class GameState:     # keep definition as before   class GameStateAdapter(Adapter):     js_constructor = 'draughts.GameState'      def js_args(self, game_state):         return [game_state.pieces]      class Media:         js = ['draughts.js']   register(GameStateAdapter(), GameState)

此處js_constructor是JavaScript建構子的標識符,該標識符將用於在客戶端上建立GameState實例,並且js_args定義了將傳遞給此構造函數的參數列表,以重新建立給定game_state物件的JavaScript對應物件 。 Media類別指示文件,該文件遵循Django對格式媒體的約定,可在其中找到GameState的JavaScript實作。稍後我們將看到此JavaScript實作的外觀,現在,我們需要為Piece類別定義一個類似的適配器,因為我們對GameStateAdapter的定義取決於是否能夠打包Piece實例。將以下定義新增至games/views.py:

class Piece:     # keep definition as before   class PieceAdapter(Adapter):     js_constructor = 'draughts.Piece'      def js_args(self, piece):         return [piece.color, piece.position]      class Media:         js = ['draughts.js']   register(PieceAdapter(), Piece)

重新載入頁面,您將看到錯誤提示消失了,這表示我們已成功將GameState物件序列化為JSON並將其傳遞給範本。現在,我們可以將其包含在模板中-編輯games/templates/game.html:

        <h2 id="Draughts">Draughts</h2>        <div>        </div>    

再次重新載入頁面,並在瀏覽器的開發人員工具中檢查遊戲元素(在Chrome和Firefox中,右鍵點選TODO註釋,然後選擇Inspect或Inspect  Element),您將看到GameState物件的JSON表示,準備好解壓成完整的JavaScript物件。

除了將資料打包成JSON可序列化的格式外,JSContext物件還追蹤將資料解壓縮所需的JavaScript媒體定義,作為其媒體屬性。讓我們更新遊戲視圖,以將其也傳遞給模板-在games/views.py中:

def game(request):     game_state = GameState.new_game()      js_context = JSContext()     packed_game_state = js_context.pack(game_state)     game_state_json = json.dumps(packed_game_state)      return render(request, 'game.html', {         'game_state_json': game_state_json,         'media': js_context.media,     })

將下面程式碼新增至games / templates / game.html中的HTML頭檔:

         <title>Draughts</title>         {{ media }}         <script>             document.addEventListener(&#39;DOMContentLoaded&#39;, event => {                 const gameElement = document.getElementById(&#39;game&#39;);                 gameElement.innerHTML = &#39;TODO: render the board here&#39;             });         </script>     

重新加载页面并查看源代码,您将看到这带来了两个JavaScript包括 ——  telepath.js(客户端telepath库,提供解包机制)和我们在适配器定义中指定的draughts.js文件。后者尚不存在,所以让我们在games /  static / draughts.js中创建它:

class Piece {     constructor(color, position) {         this.color = color;         this.position = position;     } } window.telepath.register('draughts.Piece', Piece);   class GameState {     constructor(pieces) {         this.pieces = pieces;     } } window.telepath.register('draughts.GameState', GameState);

这两个类定义实现了我们先前在适配器对象中声明的构造函数-构造函数接收的参数是js_args定义的参数。window.telepath.register行将这些类定义附加到通过js_constructor指定的相应标识符。现在,这为我们提供了解压缩JSON所需的一切-回到games  / templates / game.html中,更新JS代码,如下所示:

<script>            document.addEventListener(&#39;DOMContentLoaded&#39;, event => {                const gameElement = document.getElementById(&#39;game&#39;);                const gameStateJson = gameElement.dataset.gameState;                const packedGameState = JSON.parse(gameStateJson);                const gameState = window.telepath.unpack(packedGameState);                console.log(gameState);            })        </script>

您可能需要重新启动服务器以获取新的games/static文件夹。重新加载页面,然后在浏览器控制台中,您现在应该看到填充了Piece对象的GameState对象。现在,我们可以继续在games/static/draughts.js中填写渲染代码:

class Piece {     constructor(color, position) {         this.color = color;         this.position = position;     }      render(container) {         const element = document.createElement('div');         container.appendChild(element);         element.style.width = element.style.height = '24px';         element.style.border = '2px solid grey';         element.style.borderRadius = '14px';         element.style.backgroundColor = this.color;     } } window.telepath.register('draughts.Piece', Piece)   class GameState {     constructor(pieces) {         this.pieces = pieces;     }      render(container) {         const table = document.createElement('table');         container.appendChild(table);         const cells = [];         for (let y = 0; y  {             const [x, y] = piece.position;             const cell = cells[y][x];             piece.render(cell);         });     } } window.telepath.register('draughts.GameState', GameState)

在games/templates/game.html中添加对render方法的调用:

<script>             document.addEventListener(&#39;DOMContentLoaded&#39;, event => {                 const gameElement = document.getElementById(&#39;game&#39;);                 const gameStateJson = gameElement.dataset.gameState;                 const packedGameState = JSON.parse(gameStateJson);                 const gameState = window.telepath.unpack(packedGameState);                 gameState.render(gameElement);             })         </script>

重新加载页面,您将看到我们的跳棋程序已准备就绪,可以开始游戏了。

  • 让我们快速回顾一下我们已经取得的成果:

  • 我们已经打包和解包了自定义Python /  JavaScript类型的数据结构,而无需编写代码来递归该结构。如果我们的GameState对象变得更复杂(例如,“棋子”列表可能变成棋子和国王对象的混合列表,或者状态可能包括游戏历史),则无需重构任何数据打包/拆包逻辑,除了为每个使用的类提供一个适配器对象。

  • 仅提供了解压缩页面数据所需的JS文件-如果我们的游戏应用程序扩展到包括Chess,Go和Othello,并且所有生成的类都已通过Telepath注册,则我们仍然只需要提供与跳棋知识相关的代码。

即使我们使用任意对象,也不需要动态内联JavaScript ——  所有动态数据都以JSON形式传递,并且所有JavaScript代码在部署时都是固定的(如果我们的网站强制执行CSP,这一点很重要)。

以上是Python和JavaScript間交換資料的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除
Python的主要目的:靈活性和易用性Python的主要目的:靈活性和易用性Apr 17, 2025 am 12:14 AM

Python的靈活性體現在多範式支持和動態類型系統,易用性則源於語法簡潔和豐富的標準庫。 1.靈活性:支持面向對象、函數式和過程式編程,動態類型系統提高開發效率。 2.易用性:語法接近自然語言,標準庫涵蓋廣泛功能,簡化開發過程。

Python:多功能編程的力量Python:多功能編程的力量Apr 17, 2025 am 12:09 AM

Python因其簡潔與強大而備受青睞,適用於從初學者到高級開發者的各種需求。其多功能性體現在:1)易學易用,語法簡單;2)豐富的庫和框架,如NumPy、Pandas等;3)跨平台支持,可在多種操作系統上運行;4)適合腳本和自動化任務,提升工作效率。

每天2小時學習Python:實用指南每天2小時學習Python:實用指南Apr 17, 2025 am 12:05 AM

可以,在每天花費兩個小時的時間內學會Python。 1.制定合理的學習計劃,2.選擇合適的學習資源,3.通過實踐鞏固所學知識,這些步驟能幫助你在短時間內掌握Python。

Python與C:開發人員的利弊Python與C:開發人員的利弊Apr 17, 2025 am 12:04 AM

Python適合快速開發和數據處理,而C 適合高性能和底層控制。 1)Python易用,語法簡潔,適用於數據科學和Web開發。 2)C 性能高,控制精確,常用於遊戲和系統編程。

Python:時間投入和學習步伐Python:時間投入和學習步伐Apr 17, 2025 am 12:03 AM

學習Python所需時間因人而異,主要受之前的編程經驗、學習動機、學習資源和方法及學習節奏的影響。設定現實的學習目標並通過實踐項目學習效果最佳。

Python:自動化,腳本和任務管理Python:自動化,腳本和任務管理Apr 16, 2025 am 12:14 AM

Python在自動化、腳本編寫和任務管理中表現出色。 1)自動化:通過標準庫如os、shutil實現文件備份。 2)腳本編寫:使用psutil庫監控系統資源。 3)任務管理:利用schedule庫調度任務。 Python的易用性和豐富庫支持使其在這些領域中成為首選工具。

Python和時間:充分利用您的學習時間Python和時間:充分利用您的學習時間Apr 14, 2025 am 12:02 AM

要在有限的時間內最大化學習Python的效率,可以使用Python的datetime、time和schedule模塊。 1.datetime模塊用於記錄和規劃學習時間。 2.time模塊幫助設置學習和休息時間。 3.schedule模塊自動化安排每週學習任務。

Python:遊戲,Guis等Python:遊戲,Guis等Apr 13, 2025 am 12:14 AM

Python在遊戲和GUI開發中表現出色。 1)遊戲開發使用Pygame,提供繪圖、音頻等功能,適合創建2D遊戲。 2)GUI開發可選擇Tkinter或PyQt,Tkinter簡單易用,PyQt功能豐富,適合專業開發。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境