type(class_name, base_class, attrs)
# example
newclass = type("newcls", (), )
a = newclass()
a.name
我們用type成功生成了乙個類,他的意義在於,我可以在程式執行的過程中,使用**動態的去定義乙個類(*區別於那種傳統的先用class定義完你用的類,然後例項化使用的方式*)
這裡使用type,將乙個字典或者列表,動態的轉化生成乙個類陣列
def upper_attr(class_name, class_parents, class_attr):
attrs = ((name, value)
for name, value in class_attr.items() if not name.startswith('__'))
uppercase_attrs = dict((name.upper(), value) for name, value in attrs)
return type(class_name, class_parents, uppercase_attrs)
class newcls(metaclass=upper_attr):
name = "lanix"
*** = "male"
newcls.name # lanix
newcls.name # attributeerror: type object 'newcls' has no attribute 'name'
很明顯,類定義時通過乙個metaclass可以把定義的attrs中的屬性key,全部變為大寫, metaclass除了可以接受乙個函式,也可以介紹乙個type作為基類的類。類如
class upperattrmetaclass(type):
def __new__(mcs, class_name, class_parents, class_attr):
attrs = ((name, value) for name, value in class_attr.items() if not name.startswith('__'))
uppercase_attrs = dict((name.upper(), value) for name, value in attrs)
return super(upperattrmetaclass, mcs).__new__(mcs, class_name, class_parents, uppercase_attrs)
class newcls(metaclass=upperattrmetaclass):
name = "lanix"
*** = "male"
兩者可以實現同樣的效果
在py2中, 使用元類(metaclass)可以這麼寫, 很多介紹metaclass的文章都是這樣介紹的,而且當__metaclass__ = mymetaclass 跟類定義同級別時,會成為所有同級別的類的元類。
class newclass:
__metaclass__ = mymetaclass
但是在py3版本中, 並不支援__metaclass__的寫法,應該
class newclass(metaclass=mymetaclass):
pass
最簡單的方式可以
class badman:
def __init__(self, name):
self.name = name
self.state = ''
def run(self):
print(f' is runing!')
self.state = "run"
def fight(self):
print(f' is fighting')
self.state = "fight"
b = badman("bob")
b.run()
定義都是固定不變的,不夠靈活 ,也不夠優雅。這裡有乙個使用metaclass的例子, 可以使用metaclass寫乙個fsm。
class action(object):
def __init__(self, act_desc):
self.desc = act_desc
class manmeta(type):
def __new__(cls, name, bases, attrs):
actives = {}
for k, v in attrs.items():
if isinstance(v, action):
cls.add_action(actives, k, v)
attrs.update(actives)
return type.__new__(cls, name, bases, attrs)
@classmethod
def add_action(cls, action_dict, active_name, action_obj):
def active(self):
self.state = active_name
print(action_obj.desc)
action_dict[active_name] = active
class hero(object, metaclass=manmeta):
walk = action("from on place to another")
fight = action("use weapon to fight")
die = action("your hero is dying now")
sleep = action("fall asleep")
def __init__(self):
self.state = ""
這裡首先定義了乙個active動作類,用來描述各種動作,
隨後定義了乙個metaclass,並使用這個metaclass 改變了hero的建立過程,hero.walk 定義中是乙個 action 例項,在manmeta中,對這個walk這個屬性進行了修改,變為乙個類方法的定義函式,經過這一步神奇的轉換之後。
z = hero()
z.fight() # use weapon to fight
z.state # 'fight'
(給action物件新增乙個__call__(self) 也可以實現fight()呼叫,這裡為了解釋metaclass, 我們並不關心這些) Python 當中的and和or
一 and 在python 中,and 和 or 執行布林邏輯演算,如你所期待的一樣,但是它們並不返回布林值 而是,返回它們實際進行比較的值之一。舉例 1 2 3 4 5 6 a and b b and b a and b and c c 在布林上下文中從左到右演算表示式的值,如果布林上下文中的所有...
python當中的裝飾器
首先我們來說一下乙個軟體的設計原則 開閉原則,又被稱為開發封閉原則,你的 對功能的擴充套件是開放的,你的程式對修改源 是封閉的.這樣的軟體設計思路可以更好的維護和開發.開放 對功能擴充套件開放 封閉 對修改 封閉 接下來我們看裝飾器.首先我們先模擬一下女媧造人.def create print 女媧...
python當中的深淺copy
首先,我們要明確以下概念 在python中,物件按照可變不可變分為可變物件和不可變物件 可變物件 指 可以在原處修改,而不用建立新的物件 包括列表,字典,集合 不可變物件指 不支援在原處修改,只能通過表示式建立新的物件,然後把結果分配給變數 包括 數字,字串,元組 像a 3,這段 的執行過程是這樣 ...