提问人:Jodo 提问时间:10/22/2017 最后编辑:Jodo 更新时间:8/26/2022 访问量:2566
Python 可变 NamedTuple
Python 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)
答:
2赞
gambuzzi
10/22/2017
#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
评论
0赞
Jodo
10/22/2017
实际上,我之前已经尝试过了。但是类型提示不是这样工作的。我可能没有在我的问题中说明这一点。
1赞
viddik13
10/27/2017
类型提示将不起作用,因为它们不在初始化中
0赞
maor10
10/22/2017
#2
使用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
它(几乎)与 namedtuple 相同,并且是可变的
评论
0赞
Jodo
10/22/2017
我更喜欢内置的。不过,我也不明白如何使用类型提示。
0赞
maor10
10/22/2017
您确定这不适用于您的 IDE 吗?ipython 知道使用 recordclass 自动完成
0赞
Jodo
10/22/2017
我从来没有说过它不起作用。但同样,我如何在 recordclass 中使用类型提示。在我看来,这是行不通的。
0赞
intellimath
9/30/2018
Jodo:已经支持 typehints:: from recordclass import RecordClass from typing import 任何类 ConnectionConfig(RecordClass): name: str url: str port: int user: str = “” pwd: str = “” client: Any = None >>> cf = ConnectionConfig('name', 'example.com', 8080, 'qwerty', None) >>> print(cf.name, cf.url, cf.port, cf.pwd, repr(cf.client)) name example.com 8080 None None Nonerecordclass
3赞
viddik13
10/27/2017
#3
实际上,您的实现是(唯一)内置的方式:
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 中的这句话解释了这一点:
应该有一种——最好只有一种——显而易见的方法。
0赞
Jodo
10/28/2017
#4
在创建 NamedTuple 时调用“_asdict()”会将其转换为 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')])
1赞
intellimath
8/1/2021
#5
在 recordclass 库的基础上有一个紧凑的解决方案:
> 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
如果想要更快地创建实例,可以选择:
class ConnectionConfig(dataobject, fast_new=True):
name: str
url: str
port: int
user: str = ""
pwd: str = ""
client: Any = None
(注意:这个可能不太适合IDE编辑器的自动完成)
另一种选择:
>>> from recordclass import make_dataclass
>>> ConnectionConfig = make_dataclass(
"ConnectionConfig",
[('name',str), ('url',str), ('port',str),
('use',str), ('pwd',str), ('client',Any)],
defaults=(None,),
fast_new=True)
0赞
David
8/26/2022
#6
您可以使用该语句。pass
class myclass: pass
然后,您可以在使用属性之前创建属性:
myclass.a=0
myclass.b='string'
评论
0赞
Keith
1/23/2023
如果要走这条路,更简洁的方法是使用 SimpleNamespace。
评论
*args
**kwargs
**kwargs
for
eval
exec