1.元類
PyPy的源代碼中有壹個pair和壹個extendabletype。
"""
課堂上的兩個魔術:
X類:
__元類__ =可擴展類型
...
#在其他文件中...
class __extend__(X):
...#在這裏妳可以給X添加新的方法和類屬性
與第二個技巧壹起使用最有用,它讓您可以構建
方法的“自身”是壹對對象,而不僅僅是壹個:
class __extend__(pairtype(X,Y)):
屬性= 42
def方法((x,y),other,arguments):
...
pair(x,y)。屬性
pair(x,y)。方法(其他,參數)
這將基於實際的
成對的兩個對象的類(),通常使用
子類(成對)中方法/屬性重寫的規則。
有關更多信息,請參見test_pairtype。
"""
類extendabletype(類型):
" " "具有語法技巧的類型:' class __extend__(t)'實際上擴展了
' t '的定義,而不是創建壹個新的子類。"""
def __new__(cls,name,bases,dict):
if name == '__extend__ ':
對於基地中的cls:
對於鍵,dict.items()中的值:
如果key == '__module__ ':
繼續
# XXX我們還需要為腌制提供更多的東西嗎?
setattr(cls,key,value)
不返回
否則:
返回super(extendabletype,cls)。__new__(cls,name,bases,dict)
定義對(a,b):
" " "返回壹個配對對象。"""
tp = pairtype(a.__class__,b.__class__)
return tp((a,b)) # tp是tuple的子類
pairtypecache = {}
def pairtype(cls1,cls2):
" " " type(pair(a,b))是pairtype(a.__class__,b.__class__)。"""
嘗試:
pair = pairtypecache[cls1,cls2]
除了KeyError:
name = 'pairtype(%s,%s)' % (cls1。__name__,cls2。__name__)
對於cls1中的base1,bases 1 =[pair type(base 1,cls2)。__bases__]
對於cls2中的base2,base2 =[pair type(cls 1,base 2)。__bases__]
bases = tuple(bases 1+bases 2)或(tuple,# 'tuple ':最終基數
pair = pairtypecache[cls1,cls2] = extendabletype(name,bases,{})
返回對
先說extendabletype。其實評論已經說清楚了,這是C#中partial class的Python實現。
然後是pair和pairtype。Pairtype是在兩個類的基礎上創建壹個新類,它繼承自pairtype(有點繞...)或使用這兩個類的基類構造的元組。
有什麽用?可用於實現多方法。
class __extend__(pairtype(int,int)):
def foo((x,y)):
print 'int-int: %s-%s' % (x,y)
class __extend__(pairtype(bool,bool)):
定義欄((x,y)):
print 'bool-bool: %s-%s' % (x,y)
配對(假,真)。foo() #打印' int-int: False,True '
對(123,真)。foo() #打印' int-int: 123,True '
配對(假,真)。bar() #打印“bool-bool: False,True”
對(123,真)。bar() #哎呀,沒有這樣的方法
似乎在這個例子中,元類只是扮演壹個輔助角色,所有的樂趣都在那壹對中...
換另壹個。
類別GameObjectMeta(類型):
def __new__(mcls,clsname,bases,_dict):
對於k,v in _dict.items():
if isinstance(v,(list,set)):
_dict[k] = tuple(v) #不允許可變對象
cls =類型。__new__(mcls,clsname,bases,_dict)
all_gameobjects.add
對於堿基中的b:
game_objects_hierarchy.add((b,cls))
返回cls
@靜態方法
def _dump_gameobject_hierarchy():
用open('/dev/shm/gomap.dot ',' w ')作為f:
f . write(' di graph { \ nrankdir = LR;\n ')
f.write('\n ')。加入([
" % s "->;" % s ";"% (a.__name__,b.__name__)
對於遊戲對象層次結構中的a,b
]))
f.write('} ')
def __setattr__(cls,field,v):
類型。__setattr__(cls,field,v)
if字段在(' ui_meta ',):
返回
log.warning('SetAttr: %s,%s = %s' % (cls。__name__,field,repr(v)))
這是從我寫的三國殺遊戲中摘錄的壹段代碼(點擊我簽名上的鏈接)。主要思想是把類上的所有可變容器都改成不可變容器,然後記錄繼承關系。
我已經被這個問題騙了,上綱上線的價值是全世界都享受的。邏輯代碼不小心修改了類上的值,單機測試的時候測不出來,然後就上線了...這是壹場悲劇...我當時絞盡腦汁,沒想到問題被硬生生的回滾了...發現問題後,我加了這個東西,不允許修改類上的東西。
記錄繼承關系就是畫類圖。
還有就是常用的數據註入。
元數據= {}
def gen_metafunc(_for):
def metafunc(clsname,bases,_dict):
meta_for = getattr(_for,clsname)
meta _ for . ui _ meta = uimeta descriptor()
如果元數據中有meta_for:
引發異常(' %s ui_meta重定義!'% meta_for)
元數據[meta_for] = _dict
返回元函數
從gamepack.thb導入字符
_ _ metaclass _ _ = gen _ metafunc(characters . sakuya)
咲夜等級:
#所以這不是壹個類,而是作為數據存儲在dict元數據中。
Char_name = u '十六夜咲夜'
port _ image = ' THB-portrait-sakuya '
figure _ image = ' THB-figure-sakuya '
miss _ sound _ effect = ' th b-cv-sakuya _ miss '
描述=(
U'|DB的完全瀟灑PAD長而十六夜咲夜的體力4|r\n\n '
u“| G每月時計|r: |r:|B鎖定技術|r,在準備階段開始時,您執行壹個額外的演奏階段。\n\n '
U'|G飛刀|r:妳可以使用或打出壹張裝備卡作為彈幕。這樣使用的彈幕沒有距離限制。\n\n '
U'|DB(畫師:小D@邢幻境,CV: VV) | R '
)
不要噴紅寶石黨,我知道妳可以做得更優雅...
2.Python沙盒逃逸
樁(代碼,模。__file__,' exec ')
執行(co,mod。__字典_ _)
返回模式
例外情況為e:
統壹引擎。Debug.LogError('導入%s %s' %(全名,e)時出錯)
提升導入錯誤(e)
def do_load_module(self,fullname):
fn = fullname.replace(' . ', '/')
asset = self.try_load(fn +'。py’)
如果資產不為無:
返回資產,假
asset = self . try _ load(fn+'/_ _ init _ _)。py’)
如果資產不為無:
返回資產,真
def try_load(self,filename):
對於自我基地中的b:
asset = self.unity_load(b +文件名)
如果資產不為無:
歸還資產
不返回
sys . meta _ path . append(UnityResourceImporter([
Python/THBattle/',
Python/Site/',
Python/Stdlib/',
],WarpGateController。GetTextAsset))
所需的擴展模塊被靜態編譯到解釋器中,所以不考慮它們。
4.可以批量執行操作的列表
類批處理列表(列表):
def __getattribute__(self,name):
嘗試:
list_attr = list。__getattribute__(self,name)
返回列表_屬性
除了屬性錯誤:
及格
返回列表。__getattribute__(self,' __class__ ')(
自我中的I的getattr(i,name)
)
def __call__(self,*a,**k):
返回列表。__getattribute__(self,' __class__ ')(
f(*a,**k)為自我中的f
)
類Foo(對象):
def __init__(self,v):
self.value = v
def foo(自身):
打印“Foo!”,自我價值
foo = Foo(1)
foo.foo() # Foo!1
foos = batch list(x range(10)中I的Foo(i))
foos.value # BatchList([0,1,2,3,..., 9])
Foos.foo() #妳可以猜猜。