我正在尝试将一个冗长的空洞"数据"类转换为一个命名元组.我的班级目前看起来像这样:
class Node(object):
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
Run Code Online (Sandbox Code Playgroud)
转换为namedtuple它后看起来像:
from collections import namedtuple
Node = namedtuple('Node', 'val left right')
Run Code Online (Sandbox Code Playgroud)
但这里有一个问题.我的原始类允许我传入一个值,并使用命名/关键字参数的默认值来处理默认值.就像是:
class BinaryTree(object):
def __init__(self, val):
self.root = Node(val)
Run Code Online (Sandbox Code Playgroud)
但是这对我重构的名为元组的情况不起作用,因为它希望我传递所有字段.当然,我可以代替的出现Node(val)到Node(val, None, None),但它不是我的胃口.
所以确实存在着一个很好的技巧,它可以使我重新写成功无需添加大量的代码复杂度(元编程),或者我应该只吞下药丸,并与"查找和替换"继续前进?:)
假设我有一个带有构造函数(或其他函数)的类,它接受可变数量的参数,然后有条件地将它们设置为类属性.
我可以手动设置它们,但似乎变量参数在python中很常见,应该有一个共同的习惯用法.但我不确定如何动态地这样做.
我有一个使用eval的例子,但这几乎不安全.我想知道这样做的正确方法 - 也许是lambda?
class Foo:
def setAllManually(self, a=None, b=None, c=None):
if a!=None:
self.a = a
if b!=None:
self.b = b
if c!=None:
self.c = c
def setAllWithEval(self, **kwargs):
for key in **kwargs:
if kwargs[param] != None
eval("self." + key + "=" + kwargs[param])
Run Code Online (Sandbox Code Playgroud) 有时将相关数据聚集在一起是有意义的.我倾向于用dict这样做,例如,
self.group = dict(a=1, b=2, c=3)
print self.group['a']
Run Code Online (Sandbox Code Playgroud)
我的一位同事更喜欢创建一个班级
class groupClass(object):
def __init__(a, b, c):
self.a = a
self.b = b
self.c = c
self.group = groupClass(1, 2, 3)
print self.group.a
Run Code Online (Sandbox Code Playgroud)
请注意,我们没有定义任何类方法.
我喜欢使用dict,因为我喜欢最小化代码行数.我的同事认为如果使用类,代码更具可读性,并且将来更容易向类中添加方法.
你更喜欢哪个?为什么?
我有以下命名的元组:
from collections import namedtuple
ReadElement = namedtuple('ReadElement', 'address value')
Run Code Online (Sandbox Code Playgroud)
然后我想要以下内容:
LookupElement = namedtuple('LookupElement', 'address value lookups')
Run Code Online (Sandbox Code Playgroud)
两个命名元组之间存在重复,如何将ReadElement子类化为包含其他字段?
class LookupElement(ReadElement):
def __new__(self, address, value, lookups):
self = super(LookupElement, self).__new__(address, value)
l = list(self)
l.append(lookups)
return tuple(l)
Run Code Online (Sandbox Code Playgroud)
然而,在新语句中创建了元组,如果我将self修改为列表,我将丢失类型信息,我该如何避免这种情况?
PEP-557引入了数据类到Python标准库,基本上可以填补因为同样的作用collections.namedtuple和typing.NamedTuple.现在我想知道如何分离使用namedtuple仍然是更好的解决方案的用例.
当然,dataclass如果我们需要,所有的功劳都归功于:
property 装饰器,可管理的属性在同一个PEP中简要解释了数据类的优点:为什么不使用namedtuple.
但是对于namedtuples这个相反的问题怎么样:为什么不使用dataclass呢?我想从性能的角度来看,名字元组可能更好,但尚未确认.
让我们考虑以下情况:
我们将页面维度存储在一个小容器中,该容器具有静态定义的字段,类型提示和命名访问.不需要进一步散列,比较等.
NamedTuple方法:
from typing import NamedTuple
PageDimensions = NamedTuple("PageDimensions", [('width', int), ('height', int)])
Run Code Online (Sandbox Code Playgroud)
DataClass方法:
from dataclasses import dataclass
@dataclass
class PageDimensions:
width: int
height: int
Run Code Online (Sandbox Code Playgroud)
哪种解决方案更可取,为什么?
PS这个问题不是以任何方式重复那个问题,因为我在这里询问的是哪个命名元组更好,而不是区别(我在询问之前检查了文档和来源)
我有几个分享一些字段的命名元组.我有一个接受这些元组的函数,并保证只与共享字段交互.我想在mypy中检查这样的代码.
代码的一个例子是:
from typing import NamedTuple
class Base(NamedTuple):
x: int
y: int
class BaseExtended(NamedTuple):
x: int
y: int
z: str
def DoSomething(tuple: Base):
return tuple.x + tuple.y
base = Base(3, 4)
base_extended = BaseExtended(5, 6, 'foo')
DoSomething(base)
DoSomething(base_extended)
Run Code Online (Sandbox Code Playgroud)
当我在这段代码上运行mypy时,我得到一个可预测的错误:
mypy_example.py:20:错误:"DoSomething"的参数1具有不兼容的类型"BaseExtended"; 预期"基地"
有没有办法构建我的代码并保持mypy typechecking?我不能从Base继承BaseExtended,因为NamedTuple继承实现中存在一个错误:
https://github.com/python/typing/issues/427
我也不想使用一个丑陋的"Union [Base,BaseExtended]",因为当我尝试对一个List进行类型检查时会出现这种情况,因为"List [Union [Base,BaseExtended]]"不等于"List [BaseExtended] ]"由于关于变体/协变类型的一些mypy魔术:
https://github.com/python/mypy/issues/3351
我应该放弃这个想法吗?
我最近开始使用数据类,它们将是3.7的一个很好的补充.我很好奇是否或如何使用数据类重新创建此类的相同功能.
class Nav(object):
def __init__(self, name:str, menu, page, *submenus):
self.name = name
self.menu = menu
self.page = page
self.submenus = submenus
foo = Nav("name", "menu", "page")
Run Code Online (Sandbox Code Playgroud)
这不起作用.提出例外TypeError: __init__() missing 1 required positional argument: 'submenus'
@dataclass
class Nav(object):
name:str
menu: Any
page: Any
submenus: tuple
foo = Nav("name", "menu", "page")
Run Code Online (Sandbox Code Playgroud)
我假设这是因为该类没有指令来解析参数. 有没有办法指示数据类装饰器需要解压缩子菜单?
假设我在python3中有一个数据类。我希望能够哈希和排序这些对象。
我只希望它们在ID上排序/散列。
我在文档中看到,我可以只实现__hash__,但我想让datacalses为我完成工作,因为它们旨在处理此问题。
from dataclasses import dataclass, field
@dataclass(eq=True, order=True)
class Category:
id: str = field(compare=True)
name: str = field(default="set this in post_init", compare=False)
a = sorted(list(set([ Category(id='x'), Category(id='y')])))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'Category'
Run Code Online (Sandbox Code Playgroud) 我有一个非常基本的问题.
假设我调用一个函数,例如,
def foo():
x = 'hello world'
Run Code Online (Sandbox Code Playgroud)
如何让函数以这样的方式返回x,我可以将它用作另一个函数的输入或者在程序体内使用变量?
当我使用return并在另一个函数中调用该变量时,我得到一个NameError.
我有一个dataclass对象,其中包含嵌套的数据类对象.但是,当我创建主对象时,嵌套对象变成了字典:
@dataclass
class One:
f_one: int
@dataclass
class One:
f_one: int
f_two: str
@dataclass
class Two:
f_three: str
f_four: One
data = {'f_three': 'three', 'f_four': {'f_one': 1, 'f_two': 'two'}}
two = Two(**data)
two
Two(f_three='three', f_four={'f_one': 1, 'f_two': 'two'})
obj = {'f_three': 'three', 'f_four': One(**{'f_one': 1, 'f_two': 'two'})}
two_2 = Two(**data)
two_2
Two(f_three='three', f_four={'f_one': 1, 'f_two': 'two'})
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我试图将所有数据作为字典传递,但我没有得到预期的结果.然后我尝试首先构造嵌套对象并将其传递给对象构造函数,但我得到了相同的结果.
理想情况下,我想构建我的对象来得到这样的东西:
Two(f_three='three', f_four=One(f_one=1, f_two='two'))
Run Code Online (Sandbox Code Playgroud)
除了手动将嵌套字典转换为相应的数据类对象,每当访问对象属性时,有没有办法实现其他目的?
提前致谢.
这是示例代码
from typing import Dict, Union, Tuple
def select_range(data: Dict[str, Union[str, int]]) -> Tuple[int, int]:
if data['start'] and data['end']:
return data['start'], data['end']
return 1, 1
select_range({})
Run Code Online (Sandbox Code Playgroud)
Mypy输出:
mypy different_return.py
different_return.py:6: error: Incompatible return value type (got
"Tuple[Union[str, int], Union[str, int]]", expected "Tuple[int, int]")
Run Code Online (Sandbox Code Playgroud)
即使其中一个字典值是int,mypy也无法推断出这一点.
我在代码中经常使用字典作为数据结构。而不是Tuple像 Python 允许的那样返回几个值:
def do_smth():
[...]
return val1, val2, val3
Run Code Online (Sandbox Code Playgroud)
我更喜欢使用具有命名键优势的字典。但是对于复杂的嵌套字典,很难在其中导航。几年前我用 JS 编码时,我也喜欢字典,因为我可以像调用子部分一样thing.stuff.foo,IDE 帮助我处理结构。
我刚刚发现了DataClasspython 中的新内容,除了替换字典之外,我不确定这是什么原因?对于我所阅读的内容,DataClass内部无法包含函数,并且其参数的初始化已简化。
我想对此发表评论,你如何使用DataClass, 或关于 python 中的字典。
我正在尝试从文本文件中读取大量数据到字典中,并且我犯了几个小错别字,最终导致创建新的键/值对并破坏程序(这可能很烦人和痛苦)调试)。
这让我想知道是否有一种方法可以创建一个字典,在初始声明之后不能添加或删除任何键。我觉得这是必然存在的东西,但我找不到它的例子;有谁知道有什么符合要求的吗?
def change_key(dictionary, key, new_value):
a = dictionary.__len__()
dictionary[key] = new_value
if dictionary.__len__() != a:
raise ValueError("new key added")
Run Code Online (Sandbox Code Playgroud)
我正在寻找的是上面代码的更优雅的实现,即:
不是一大堆乱七八糟的代码
能够处理诸如附加到嵌套列表或添加到嵌套字典之类的事情
相当有效
python ×13
namedtuple ×4
dictionary ×2
mypy ×2
python-3.x ×2
class ×1
function ×1
hash ×1
nested ×1
object ×1
pep ×1
python-2.7 ×1
python-3.7 ×1
python-3.9 ×1
struct ×1
typing ×1