Python可变NamedTuple

时间:2017-10-21 17:16:33

标签: python struct python-3.6 mutable namedtuple

我正在寻找一个类似于数据结构的结构我可以创建多个实例,并且有一些类型提示而不是不可变的。

所以我有这样的事情:

class ConnectionConfig(NamedTuple):
    name: str
    url: str
    port: int
    user: str = ""
    pwd: str = ""
    client: Any = None

但我想让它变得可变。我可以这样做:

class ConnectionConfig():
    def __init__(self, name: str, url: str, port: int, user: str = "", pwd: str = "", client: Any = None):
        self.name = name
        self.url = url
        self.port = port
        self.user = user
        self.pwd = pwd
        self.client = client

但是男人......那很难看:/ python中有没有内置的替代品? (使用Python 3.6.3)

5 个答案:

答案 0 :(得分:2)

你的实现是(唯一的)内置方式,实际上:

class ConnectionConfig():
    def __init__(self, name: str, url: str, port: int, user: str = "",
                 pwd: str = "", client: Any = None):
        pass

阅读PEP 0484我没有找到任何符合您需求的其他选择。继续PEP链,我想PEP 20 The Zen of Python的引用解释了它:

  

应该有一个 - 最好只有一个 - 显而易见的方法。

答案 1 :(得分:1)

class ConnectionConfig():
    name: str
    url: str
    port: int
    user: str = ""
    pwd: str = ""
    client: Any = None
    def __init__(self, **kv):
        self.__dict__.update(kv)

然后你可以在构造函数中指定所有内容

c=ConnectionConfig(port=22)

print (c.port)  # will print 22

答案 2 :(得分:1)

recordclass 库的基础上有一个紧凑的解决方案:

import time
import msvcrt

t = 500
while t: # while t > 0 for clarity 
    try:
        # Timer
        mins = t // 60
        secs = t % 60
        timer = '{:02d}:{:02d}'.format(mins, secs)
        print(timer, end="\r")
        time.sleep(1)
        t -= 1
    except KeyboardInterrupt:

        # clear 
        while msvcrt.kbhit():
            msvcrt.getch()

        response = input("-- Press 'enter' to unpause \
                        \n-- Type s to skip timer \
                        \n-- Type e to close program \
                        \nYour Response Here: ")
        
        

如果想要更快地创建实例,有一个选项:

> pip3 install recordclass

from recordclass import dataobject

class ConnectionConfig(dataobject):
    name: str
    url: str
    port: int
    user: str = ""
    pwd: str = ""
    client: Any = None

>>> con = ConnectionConfig('name','url',8080,'user','secret',tcp_client)

>>> sys.getsizeof(con)
108   # PyHEAD (16) + 6*sizeof(*void) bytes

(注意:这个可能不太适合 IDE 编辑器的自动完成)

另一种选择:

class ConnectionConfig(dataobject, fast_new=True):
    name: str
    url: str
    port: int
    user: str = ""
    pwd: str = ""
    client: Any = None

答案 3 :(得分:0)

如何使用recordclass(pip install recordclass)?

from recordclass import recordclass


>>> Point = recordclass('Point', 'x y')

>>> p = Point(3, 2)
>>> p
Point(x=3, y=2)
>>> p.x = 8

它(几乎)与命名元组相同的api并且它是可变的

答案 4 :(得分:0)

拨打" _asdict()"在创建NamedTuple时会将它转换为OrderedDict(),但根本不满足......

from typing import NamedTuple

class ConnectionConfig(NamedTuple):
    name: str
    url: str
    port: int
    user: str = ""
    pwd: str = ""

mutable_connection_cfg = ConnectionConfig("my_name", "my_url", 111, "my_user", "my_pwd")._asdict()

print(mutable_connection_cfg)
>> OrderedDict([('name', 'my_name'), ('url', 'my_url'), ('port', 111), ('user', 'my_user'), ('pwd', 'my_pwd')])