一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python在游戲中的熱更新實現

Python在游戲中的熱更新實現

2022-02-18 00:32香菜聊游戲 Python

本文主要介紹了Python在游戲中的熱更新實現,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

介紹:

熱更新,就是在服務器不重啟的的情況下,對游戲增加新的功能或者修復出現bug 的代碼。游戲更新迭代速度快,催生了熱更技術的需求,在我經歷過的游戲項目中,無論是服務端還是客戶端,版本的更新都是圍繞著熱更新,特別是現在游戲動輒幾個G,每次讓玩家下載完整的包不現實,隨意游戲必須要支持熱更。下面來談一下客戶端Python熱更新的處理。

原理:

1.標準import

都知道Python提供了import可以導入一個標準的python模塊,將模塊載入內存,并加到sys.modules中。但是多次import同一模塊只是將名稱導入到當前的Local名字空間,也就是一個模塊不會重復載入,所以想要熱更靠這個特性是不行的。此路不通,請換個思路。

2.reload函數

reload()函數可以重新載入已經導入的模塊,這樣似乎就可以熱更新Python的代碼了。但是python原生的reload函數太過簡單,不足以支撐游戲的熱更新需求,主要原因有幾個: reload重新加載的模塊不會替換舊版本的模塊,也就是已經引用的舊模塊無法更新 同樣因為不能舊對象的引用,使用from ... import ... 方式引用的模塊同樣不能更新 reloas(m)后,class及其派生class的實例對象,仍然使用舊的class定義。 同時加載模塊失敗時候,沒有回滾機制,導致需要重新import該模塊 因此,結合游戲的熱更新需求,自定義合適的reload。新的自定義reload目的是為了達到在原程序不結束的情況下,讓程序能動態加載改動后的代碼。主要想達到下面兩點: 提升開發效率 在游戲不重啟的情況下修復緊急BUG

實現:

熱更新最核心的需求就是讓python解釋器執行最新的代碼,同時保證其他關聯模塊不會出現問題。對于刷新function,class內定義的method比較容易實現,但對于刷新module內定義的變量,class內定義的變量,還有新增加的成員變量,則需要有統一的約定。所以在實現熱更新過程中,我們需要考慮好代碼更新和數據更新這兩點,下面羅列一下新的reload具備哪些特性:

1.更新代碼定義(function/method/static_method/class_method) 不更新數據(除了代碼定義外的類型都當作是數據) 在module中約定reload_module接口,class中約定reload_class接口,在這兩個接口中手動處理數據的更新,還有更多的約定和接口待完成 替換函數對象的內容

?
1
2
3
4
5
# 用新的函數對象內容更新舊的函數對象中的內容,保持函數對象本身地址不變 
def update_function(oldobj, newobj, depth=0): 
    setattr(oldobj, "func_code", newobj.func_code) 
    setattr(oldobj, "func_defaults", newobj.func_defaults) 
    setattr(oldobj, "func_doc", newobj.func_doc)

2.替換類的內容

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 用新類內容更新舊類內容,保持舊類本身地址不變 
def _update_new_style_class(oldobj, newobj, depth): 
    handlers = get_valid_handlers() 
    for k, v in newobj.__dict__.iteritems(): 
        # 如果新的key不在舊的class中,添加之 
        if k not in oldobj.__dict__: 
            setattr(oldobj, k, v) 
            _log("[A] %s : %s"%(k, _S(v)), depth) 
            continue
        oldv = oldobj.__dict__[k] 
  
        # 如果key對象類型在新舊class間不同,那留用舊class的對象 
        if type(oldv) != type(v): 
            _log("[RD] %s : %s"%(k, _S(oldv)), depth) 
            continue
  
        # 更新當前支持更新的對象 
        v_type = type(v) 
        handler = handlers.get(v_type) 
        if handler: 
            _log("[U] %s : %s"%(k, _S(v)), depth) 
            handler(oldv, v, depth + 1
            # 由于是直接改oldv的內容,所以不用再setattr了。 
        else
            _log("[RC] %s : %s : %s"%(k, type(oldv), _S(oldv)), depth) 
  
    # 調用約定的reload_class接口,處理類變量的替換邏輯 
    object_list = gc.get_referrers(oldobj) 
    for obj in object_list: 
        # 只有類型相同的才是類的實例對象 
        if obj.__class__.__name__ != oldobj.__name__: 
            continue
        if hasattr(obj, "x_reload_class"): 
            obj.x_reload_class()

3.staticmethod

?
1
2
3
4
5
def _update_staticmethod(oldobj, newobj, depth): 
    # 一個staticmethod對象,它的 sm.__get__(object)便是那個function對象 
    oldfunc = oldobj.__get__(object
    newfunc = newobj.__get__(object
    update_function(oldfunc, newfunc, depth)

4.classmethod

?
1
2
3
4
def _update_classmethod(oldobj, newobj, depth): 
    oldfunc = oldobj.__get__(object).im_func 
    newfunc = newobj.__get__(object).im_func 
    update_function(oldfunc, newfunc, depth)

模塊的更新也是相類似,就不一一粘貼了,只是在原來的reload基礎上進行改良,對于模塊熱更新,還約定了一個reload_module接口,可以自定義數據的更新。 下面添加一些用例:

?
1
2
3
4
5
6
7
def x_reload_class(self): 
    """ 熱更新后,每個重新對象的實例都會執行這個函數
    由于新老對象的替換不會重新調用構造函數,因此有必要對熱更新的類對象執行初始化邏輯
    處理新老變量的修復,函數執行環境的修復
    """
    self._new_var = 5000    # 新變量的初始化 
    self.runLogic()      # 新修復的邏輯

總結:

只是在基礎的reload模塊上做了一些定制,讓熱更新更適合游戲的開發節奏,而不是簡單暴力的reload模塊

到此這篇關于Python在游戲中的熱更新實現的文章就介紹到這了,更多相關Python 熱更新內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://juejin.cn/post/7022904502197944328

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色久天| 免费看一级a一片毛片 | 日韩国产成人精品视频人 | 四虎国产精品视频免费看 | 日韩操比视频 | 亚洲人成网站在线观看播放青青 | 91在线视频导航 | 视频一区二区国产无限在线观看 | 娇妻与公陈峰姚瑶小说在线阅读 | 富士av105| 色中色官网| 奇米影视999 | 韩国甜性涩爱免费观看 | 动漫白丝袜美女羞羞 | 国产精品免费久久久久影院 | 天天摸天天爽视频69视频 | 小草观看免费高清视频 | 好大好猛好爽好深视频免费 | xxx中国bbbwww| 精品国产91久久久久久久 | 91午夜视频 | 欧美高清无砖专区欧美精品 | 久久久免费热线精品频 | 亚洲国产精品综合久久一线 | 婷婷丁香视频 | 国产123区在线视频观看 | pron在线观看 | 国产亚洲欧美日韩俺去了 | 久久亚洲电影www电影网 | 无码射肉在线播放视频 | 无限在线观看视频大全免费高清 | 国产亚洲欧美成人久久片 | 暖暖影院日本版 | 女王脚奴vk | 秘书在办公室疯狂被hd | 给我免费观看的视频在线播放 | 青青青青青 | 亚洲男gay同性同志 亚洲免费在线看 | 免费在线视频网站 | 91精品天美精东蜜桃传媒免费 | 久久精麻豆亚洲AV国产品 |