pydantic:在班级的所有实例中进行迭代

发布于 2025-01-26 22:30:49 字数 1240 浏览 1 评论 0原文

我想迭代Pydantic的所有类(服务器)的现有实例:

from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel
from pydantic.schema import schema

class Share(BaseModel):
    exportstring: str
    mountpoint: str
    options: str

class Server(BaseModel):
    srvname: str
    shares: List[Share]

class ServerList(BaseModel):
    __root__: List[Server]

    def __iter__(self):
        return iter(self.__root__)

    def __getitem__(self, Server):
        return self.__root__[Server]

srv1 = Server(srvname="horst1", shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])

srv1 = Server(srvname="harry", shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])

我试图使用这种Metaclass ServerListe,但没有成功……

类似这样的事情是行不通的:

for item in ServerList:
    print(item)

有什么想法吗?

I want to iterate over all existing instances of a class (server) in pydantic:

from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel
from pydantic.schema import schema

class Share(BaseModel):
    exportstring: str
    mountpoint: str
    options: str

class Server(BaseModel):
    srvname: str
    shares: List[Share]

class ServerList(BaseModel):
    __root__: List[Server]

    def __iter__(self):
        return iter(self.__root__)

    def __getitem__(self, Server):
        return self.__root__[Server]

srv1 = Server(srvname="horst1", shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])

srv1 = Server(srvname="harry", shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])

I tried to use this kind of metaclass Serverliste but without success...

Something like this doesn't work:

for item in ServerList:
    print(item)

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

江南月 2025-02-02 22:30:49

您可以通过编写自己的__ Init __来做到这一点,调用超级__ init __ init __将实例注册到某些注册表(此处的列表),然后迭代注册表。

技巧不在__ Init __管道中。诀窍是Pydantic class创建机制(赌某个地方的Metaclass)删除了它不像Bona实例级别的Pydantic领域。因此,我不得不将server_list放在班级外。

from datetime import datetime
from typing import List, Optional, Any
from pydantic import BaseModel
from pydantic.schema import schema



class Share(BaseModel):
    exportstring: str
    mountpoint: str
    options: str


class Server(BaseModel):
    srvname: str
    shares: List[Share]

    #this doesn't worker.  The actual server class only gets declared
    #pydantics fields and pydantic utility methods/variables.
    #list : Any = []

    def __init__(self, *args, **kwargs):
        super(Server,self).__init__(*args,**kwargs)
        server_list.append(self)

#have to declare standalone variable, or at least one outside
#of pydantic class definitions
server_list = []


srv1 = Server(srvname="horst1", shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])
srv2 = Server(srvname="harry", shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])

#hardcoded iteration
for srv in [srv1,srv2]:
    print(f"\n\n{srv=}")

# for srv2 in Server.list:

#registered by class 
for srv2 in server_list:
    print(f"\n\n{srv2=}")

输出:



srv=Server(srvname='horst1', shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])


srv=Server(srvname='harry', shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])


srv2=Server(srvname='horst1', shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])


srv2=Server(srvname='harry', shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])

You can do it by writing your own __init__, calling the super's __init__ registering the instance to some registry (a list here) and then iterating the registry.

The trick isn't in the __init__ plumbing. The trick is that pydantic class creation mechanism (bet there's a metaclass somewhere) removes anything it doesn't see as a bona instance-level pydantic field. So I had to put server_list outside of the class.

from datetime import datetime
from typing import List, Optional, Any
from pydantic import BaseModel
from pydantic.schema import schema



class Share(BaseModel):
    exportstring: str
    mountpoint: str
    options: str


class Server(BaseModel):
    srvname: str
    shares: List[Share]

    #this doesn't worker.  The actual server class only gets declared
    #pydantics fields and pydantic utility methods/variables.
    #list : Any = []

    def __init__(self, *args, **kwargs):
        super(Server,self).__init__(*args,**kwargs)
        server_list.append(self)

#have to declare standalone variable, or at least one outside
#of pydantic class definitions
server_list = []


srv1 = Server(srvname="horst1", shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])
srv2 = Server(srvname="harry", shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])

#hardcoded iteration
for srv in [srv1,srv2]:
    print(f"\n\n{srv=}")

# for srv2 in Server.list:

#registered by class 
for srv2 in server_list:
    print(f"\n\n{srv2=}")

output:



srv=Server(srvname='horst1', shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])


srv=Server(srvname='harry', shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])


srv2=Server(srvname='horst1', shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])


srv2=Server(srvname='harry', shares=[Share(exportstring='export1server:/vol/asdfasdf', mountpoint='/opt/bla', options='nfsvers=4,rw,sync'), Share(exportstring='export1server:/vol/blub', mountpoint='/opt/bluba', options='nfsvers=4,rw,sync')])

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文