中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python在游戲中如何進行熱更新處理

發布時間:2021-10-27 09:08:22 來源:億速云 閱讀:224 作者:小新 欄目:開發技術

小編給大家分享一下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接口,在這兩個接口中手動處理數據的更新,還有更多的約定和接口待完成 替換函數對象的內容

    # 用新的函數對象內容更新舊的函數對象中的內容,保持函數對象本身地址不變  
    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.替換類的內容

    # 用新類內容更新舊類內容,保持舊類本身地址不變  
    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

    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

    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接口,可以自定義數據的更新。 下面添加一些用例:

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

    看完了這篇文章,相信你對“Python在游戲中如何進行熱更新處理”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    米林县| 横山县| 武平县| 吉林省| 雅安市| 万源市| 绥阳县| 新龙县| 潜江市| 松阳县| 苗栗县| 万盛区| 玛纳斯县| 班戈县| 同江市| 噶尔县| 垦利县| 白河县| 包头市| 偃师市| 会东县| 宾川县| 迁安市| 九龙城区| 林西县| 务川| 武安市| 比如县| 鹤庆县| 新郑市| 文成县| 富川| 昭平县| 湘潭市| 阿城市| 天祝| 大厂| 洪湖市| 讷河市| 武定县| 闻喜县|