日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python枚举类的意义_用于ORM目的的python枚举类

發(fā)布時間:2025/3/8 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python枚举类的意义_用于ORM目的的python枚举类 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

編輯問題

我正在嘗試創(chuàng)建一個類工廠,它可以生成具有以下屬性的枚舉類:

>從列表中初始化類

允許值(即,它)

自動生成!).

> Class創(chuàng)建自己的一個實例

對于每個允許的值.

>類不允許創(chuàng)建

任何其他實例一旦

上述步驟已完成(任何嘗試

這樣做會導致異常).

>類實例提供了一種方法

這個,給定一個值,返回一個

參考相應的

實例.

>類實例只有兩個

屬性:id和value.該

屬性id自動遞增

每個新實例;屬性

value是實例的值

代表.

>類是可迭代的.我更喜歡

使用the accepted

answer to another SO question實現(xiàn)這一點

(具體來說,通過利用課程

注冊表和定義iter

我的元類中的方法

枚舉類是實例).

這就是我正在尋找的.請將原始文本(下方)視為問題的背景.很抱歉從一開始就不清楚.

更新的答案

我對aaronasterling的非常有用的答案做了一些修改.我以為我會在這里展示,以便其他人可以受益,所以如果我做錯了,我會收到更多評論:)

我做的修改是:

(0)移植到p3k(iteritems – > items,元類 – >’metaclass =’,無需指定對象作為基類)

(1)將實例方法更改為@classmethod(現(xiàn)在我不需要對象來調用它,只需要類)

(2)我不是一舉填充_registry,而是每次構造一個新元素時都更新它.這意味著我可以使用它的長度來設置id,所以我擺脫了_next_id屬性.它也適用于我計劃的擴展(見下文).

(3)從enum()中刪除了classname參數(shù).畢竟,該類名將是一個本地名稱;無論如何,全局名稱必須單獨設置.所以我使用了一個虛擬’XXX’作為本地類名.我有點擔心第二次調用該函數(shù)時會發(fā)生什么,但它似乎有效.如果有人知道原因,請告訴我.如果這是一個壞主意,我當然可以在每次調用時自動生成一個新的本地類名.

(4)擴展此類以允許用戶添加新的枚舉元素的選項.具體來說,如果使用不存在的值調用instance(),則會創(chuàng)建相應的對象,然后由該方法返回.如果我從解析文件中獲取大量枚舉值,這將非常有用.

def enum(values):

class EnumType(metaclass = IterRegistry):

_registry = {}

def __init__(self, value):

self.value = value

self.id = len(type(self)._registry)

type(self)._registry[value] = self

def __repr__(self):

return self.value

@classmethod

def instance(cls, value):

return cls._registry[value]

cls = type('XXX', (EnumType, ), {})

for value in values:

cls(value)

def __new__(cls, value):

if value in cls._registry:

return cls._registry[value]

else:

if cls.frozen:

raise TypeError('No more instances allowed')

else:

return object.__new__(cls)

cls.__new__ = staticmethod(__new__)

return cls

原文

我使用SQLAlchemy作為對象關系映射工具.它允許我將類映射到SQL數(shù)據(jù)庫中的表.

我有幾節(jié)課.一個類(Book)是具有一些實例數(shù)據(jù)的典型類.其他(流派,類型,封面等)都是基本的枚舉類型;例如,流派只能是’科幻’,’浪漫’,’漫畫’,’科學’;封面只能是“硬”,“軟”;等等. Book與其他每個類之間存在多對一的關系.

我想半自動生成每個枚舉樣式的類.請注意,SQLAlchemy要求’scifi’表示為類Genre的實例;換句話說,簡單地定義Genre.scifi = 0,Genre.romance = 1等是行不通的.

我嘗試編寫一個元類枚舉,它接受類的名稱和允許值列表作為參數(shù).我希望如此

Genre = enum('Genre', ['scifi', 'romance', 'comic', 'science'])

會創(chuàng)建一個允許這些特定值的類,并且還可以創(chuàng)建我需要的每個對象:類型(‘科幻’),流派(‘浪漫’)等.

但我被卡住了.一個特別的問題是,在ORM意識到這個類之前我無法創(chuàng)建Genre(‘scifi’);另一方面,當ORM知道Genre時,我們不再是類構造函數(shù)了.

另外,我不確定我的方法是好的開始.

任何意見,將不勝感激.

解決方法:

基于更新的新答案

我認為這滿足了您所有指定的要求.如果沒有,我們可以添加你需要的任何東西.

def enum(classname, values):

class EnumMeta(type):

def __iter__(cls):

return cls._instances.itervalues()

class EnumType(object):

__metaclass__ = EnumMeta

_instances = {}

_next_id = 0

def __init__(self, value):

self.value = value

self.id = type(self)._next_id

type(self)._next_id += 1

def instance(self, value):

return type(self)._instances[value]

cls = type(classname, (EnumType, ), {})

instances = dict((value, cls(value)) for value in values)

cls._instances = instances

def __new__(cls, value):

raise TypeError('No more instances allowed')

cls.__new__ = staticmethod(__new__)

return cls

Genre = enum('Genre', ['scifi', 'comic', 'science'])

for item in Genre:

print item, item.value, item.id

assert(item is Genre(item.value))

assert(item is item.instance(item.value))

Genre('romance')

老答案

回應你對Noctis Skytower答案的評論,其中你說你想要Genre.comic =流派(‘漫畫’)(未經(jīng)測試):

class Genre(GenreBase):

genres = ['comic', 'scifi', ... ]

def __getattr__(self, attr):

if attr in type(self).genres:

self.__dict__[attr] = type(self)(attr)

return self.__dict__[attr]

這將創(chuàng)建一個類型實例,以響應嘗試訪問它并將其附加到請求它的實例.如果您希望將它附加到整個類,請?zhí)鎿Q該行

self.__dict__[attr] == type(self)(attr)

type(self).__dict__[attr] = type(self)(attr)

這使得所有子類都創(chuàng)建子類的實例以響應請求.如果您希望子類創(chuàng)建Genre的實例,請將type(self)(attr)替換為Genre(attr)

標簽:python,enumeration,sqlalchemy

總結

以上是生活随笔為你收集整理的python枚举类的意义_用于ORM目的的python枚举类的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。