Python元類與列舉類

隔夜的周發表於2019-02-16

一、元類

1、type()函式可以返回物件的型別,也可以建立出新的型別。它可以改變類建立時的行為,實現動態建立類。

# 第一個引數:類名
# 第二個引數:父類元祖
# 第三個引數:屬性、方法
A = type("A",(object,),{"name":"zhou"})
a = A()
print(type(A)) # <class `type`>
print(type(a)) # <class `__main__.A`>
print(a.name) # zhou

2、可以通過metaclass指定類的元類

class MyType(type):
    pass

class A(metaclass=MyType):
    pass

print(type(A)) # <class `__main__.MyType`>

另一種指定函式元類(轉載):

def upper_attr(future_class_name, future_class_parents, future_class_attr):
    attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith(`__`))
    uppercase_attr = dict((name.upper(), value) for name, value in attrs)
    return type(future_class_name, future_class_parents, uppercase_attr)

class Foo(metaclass = upper_attr): # 指定元類
    bar = `bip`

print(hasattr(Foo, `bar`))
# 輸出: False
print(hasattr(Foo, `BAR`))
# 輸出:True

二、列舉類

在開發中經常設定多組常量,Enum可以把一組相關常量定義在一個class中,且class不可變,而且成員可以直接比較。

from enum import Enum

pay_methods = Enum("PayMethods",("CASH","WEIXIN","ALIPAY","UNIONPAY",))

for name, member in pay_methods.__members__.items():
    print(name, `,`, member, `,`, member.value)
# CASH , PayMethods.CASH , 1
# WEIXIN , PayMethods.WEIXIN , 2
# ALIPAY , PayMethods.ALIPAY , 3
# UNIONPAY , PayMethods.UNIONPAY , 4
# value屬性則是自動賦給成員的int常量,預設從1開始計數。

也可以通過繼承Enum類來自定義:

from enum import Enum, unique


@unique  # 幫助我們檢查是否重複
class PayMethods(Enum):
    CASH = 0  # 設定CASH.value = 0
    WEIXIN = 1
    ALIPAY = 2
    UNIONPAY = 3


print(PayMethods[`CASH`])  # PayMethods.CASH
print(PayMethods(1))  # PayMethods.WEIXIN
print(PayMethods.ALIPAY.value)  # 2

相關文章