所以我有两个简单的 ctypes 结构
class S2 (ctypes.Structure):
_fields_ = [
('A2', ctypes.c_uint16*10),
('B2', ctypes.c_uint32*10),
('C2', ctypes.c_uint32*10) ]
class S1 (ctypes.Structure):
_fields_ = [
('A', ctypes.c_uint16),
('B', ctypes.c_uint32),
('C', S2) ]
Run Code Online (Sandbox Code Playgroud)
例如,是否可以使用namedtuple 执行相同的操作?nametuple 中如何处理列表?
编辑:
结构包用法
test_data = '0100000002000000' + 10*'01' + 10*'01' + 10*'01'
S2 = collections.namedtuple('S2', ['A2', 'B2', 'C2'])
S1 = collections.namedtuple('S1', ['A', 'B', 'REF_to_S2'])
Data2 = S2._make(struct.unpack('10p10p10p', binascii.unhexlify(test_data[16:])))
##this is not working, because there must be 3 args..
Data1 = S1._make(struct.unpack('ii', binascii.unhexlify(test_data[0:16])))
Run Code Online (Sandbox Code Playgroud)
最后我想以可读格式打印数据(具有可见的键:值对)。但现在我不知道应该如何处理两个不同的命名元组的解包操作......?
这个 unpack.struct 操作会处理值类型问题,对吗?
是否可以创建一个继承自多个实例的类namedtuple,或者创建具有相同效果的类(具有组合基类型字段的不可变类型)?我还没有找到办法.
这个例子说明了这个问题:
>>> class Test(namedtuple('One', 'foo'), namedtuple('Two', 'bar')):
>>> pass
>>> t = Test(1, 2)
TypeError: __new__() takes 2 positional arguments but 3 were given
>>> t = Test(1)
>>> t.foo
1
>>> t.bar
1
Run Code Online (Sandbox Code Playgroud)
问题似乎是namedtuple不super用于初始化其基类,如创建一个时可以看到:
>>> namedtuple('Test', ('field'), verbose=True)
[...]
class Test(tuple):
[...]
def __new__(_cls, field,):
'Create new instance of Test(field,)'
return _tuple.__new__(_cls, (field,))
Run Code Online (Sandbox Code Playgroud)
即使我考虑编写自己的版本namedtuple来解决这个问题,但如何做到这一点并不明显.如果namedtuple类的MRO中有多个实例,则它们必须共享基类的单个实例tuple.要做到这一点,他们必须协调namedtuple使用基本元组中哪个索引范围.
有没有更简单的方法来实现与namedtuple类似或类似的多重继承?有人已经在某处实现了吗?
namedtuple创建通常需要输入两次名称,一次提供包含新类的模块级变量的名称,一次设置__name__新类的属性(用于打印类对象,我认为主要用于调试,日志记录,等等.).
除了稍微出乎意料之外,使用函数(new_namedtuple下面)减少样板代码是否有任何缺点?并使用globals()正确或应该使用exec?当然,它只适用于我们希望类名和变量名相同的情况:
>>> from collections import namedtuple
>>> def new_namedtuple(name, *args, **kwargs):
... globals()[name] = namedtuple(name, *args, **kwargs)
...
>>> new_namedtuple('Point', 'x y')
>>> p = Point(x=1, y=10)
>>> p
Point(x=1, y=10)
Run Code Online (Sandbox Code Playgroud)
编辑:@Moinuddin Quadri指出进口将失败.那不好.所以让我重新解释一下我的问题:最好的方法是什么?还是不值得?
尝试在 Python3 Jupyter notebook 中运行此代码:
t = namedtuple('a', 'b')
a = [1,0,1]
b = [1,1,1]
Out, In = np.asanyarray(a), np.asanyarray(b)
t(Out.shape[0], *In.shape)
Run Code Online (Sandbox Code Playgroud)
返回错误:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-151-7955ff03a60d> in <module>()
3 b = [1,1,1]
4 Out, In = np.asanyarray(a), np.asanyarray(b)
----> 5 t(Out.shape[0], *In.shape)
TypeError: __new__() takes 2 positional arguments but 3 were given
Run Code Online (Sandbox Code Playgroud)
可以用两个参数创建namedtuple吗?
更新 :
为什么这不会导致类似的问题:
t = namedtuple('ps', 'Out In S')
a = np.asanyarray([[1]])
b = np.asanyarray([[1]])
d = t(a.shape[0], *b.shape)
d
Run Code Online (Sandbox Code Playgroud)
计算:
ps(Out=1, …Run Code Online (Sandbox Code Playgroud) 我在烧瓶视图函数中有以下内容(_我使用的是 python 3.6):
@login_required
@main.route('/dashboard', methods=['GET', 'POST'])
def dashboard():
if request.method =='POST':
dash_data = namedtuple('dash_data',[('posting', str), ('folder', str)])
print(request.form.get('posting'))
posted_data= dash_data(posting=request.form.get('posting'),folder=request.form.get('folder'))
Run Code Online (Sandbox Code Playgroud)
我越来越:
Traceback (most recent call last):
File "...\lib\site-packages\flask\app.py", line 1997, in __call__
return self.wsgi_app(environ, start_response)
File "...\lib\site-packages\flask\app.py", line 1985, in wsgi_app
response = self.handle_exception(e)
File "...\lib\site-packages\flask\app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File "...\lib\site-packages\flask\_compat.py", line 33, in reraise
raise value
File "...\lib\site-packages\flask\app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "...\lib\site-packages\flask\app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e) …Run Code Online (Sandbox Code Playgroud) 我正在努力从YouTube频道及其视频中检索元数据。
一切都很好,但是目前我正在努力将所有信息放入所需的信息中dataframe。这是我从https://gist.github.com/andkamau/0d4e312c97f41a975440a05fd76b1d29使用的以下代码github
import urllib.request
import json
from bs4 import BeautifulSoup
from collections import namedtuple
import pafy
from pandas import *
import pandas as pd
df = pd.DataFrame()
Video = namedtuple("Video", "video_id title duration views thumbnail Description")
def parse_video_div(div):
video_id = div.get("data-context-item-id", "")
title = div.find("a", "yt-uix-tile-link").text
duration = div.find("span", "video-time").contents[0].text
views = str(div.find("ul", "yt-lockup-meta-info").contents[0].text.rstrip(" views").replace(",", ""))
img = div.find("img")
videoDescription = pafy.new("https://www.youtube.com/watch?v="+video_id)
thumbnail = "http:" + img.get("src", "") if img else ""
Description = videoDescription.description …Run Code Online (Sandbox Code Playgroud) 我正在尝试namedtuple像这样腌制:
def f():
TemplateData = namedtuple('TemplateData', ['field1', 'field2'])
f1 = np.random.randn(50,50)
f2 = np.random.randn(50,50)
td = TemplateData(f1, f2)
return td
data = f()
with open("aaaa.pkl", "wb") as fl:
pkl.dump(data, fl)
Run Code Online (Sandbox Code Playgroud)
但这由于错误而崩溃:
def f():
TemplateData = namedtuple('TemplateData', ['field1', 'field2'])
f1 = np.random.randn(50,50)
f2 = np.random.randn(50,50)
td = TemplateData(f1, f2)
return td
data = f()
with open("aaaa.pkl", "wb") as fl:
pkl.dump(data, fl)
Run Code Online (Sandbox Code Playgroud)
怎么了?如果pickle不是存储命名元组的最佳方式 - 最有效的方式是什么?
如何做相反的事情?
我有一个通过迭代 Pandas 数据框构建的命名元组列表:
list = []
for currRow in dataframe.itertuples():
list.append(currRow)
Run Code Online (Sandbox Code Playgroud)
如何将此命名元组列表转换为元组列表?请注意, itertuples() 返回命名元组。
我需要构建一个像这样的数据结构:
{
key: {k: v for k in range(fixed_small_number)}
for key in range(fixed_large_number)
}
Run Code Online (Sandbox Code Playgroud)
问题是我正在以"不拘一格"的方式构建它,每次获得一个项目随机k放入一个随机密钥,即我需要随机访问,我需要内部字典是可变的.
所以我的问题分为两个:
外部字典的推荐类型.
内部字典的推荐类型.
对我来说,"最好的"解决方案是一系列可变的命名元组,只有这个不存在.
我可以使用一个namedtuples列表,然后使用新数据重新创建每个,但这听起来非常浪费,列表不是随机访问高效的,并且所有重写都是相同的数据.
我不知道有一些神奇的新结构吗?
编辑:用法示例:
for key, k, v in [('a', 1, 2), ('b', 1, 3), ('a', 2, 1), ('a', 3, 1), ('b', 3, 1) ...]:
my_structre[key][k] = v
Run Code Online (Sandbox Code Playgroud)
EDIT2:
事实证明,列表实际上支持随机访问
namedtuple在Python中覆盖对象的length方法比你想象的要冗长乏味.天真的方法,
from collections import namedtuple
class Rule(namedtuple('Rule', ['lhs', 'rhs'])):
def __len__(self):
return len(self.rhs)
r = Rule('S', ['NP', 'Infl', 'VP'])
new_r = r._replace(lhs='CP') # raises a TypeError
Run Code Online (Sandbox Code Playgroud)
不起作用.如果您检查类的实际源代码(可用作_source属性),您可以看到_make(执行哪些_replace调用和引发错误)如下所示:
@classmethod
def _make(cls, iterable, new=tuple.__new__, len=len):
'Make a new Rule object from a sequence or iterable'
result = new(cls, iterable)
if len(result) != 2:
raise TypeError('Expected 2 arguments, got %d' % len(result))
return result
Run Code Online (Sandbox Code Playgroud)
有趣的是,它检查以确保返回值的长度为2.这使得覆盖__len__元组上的方法更加困难,因为_make如果它返回长度不是2的值,则会抱怨.
通过传递len始终返回2 的" "函数可以防止此行为_make: …
我正在一个装饰器上实现不可变类的某些行为。我想要一个从namedtuple继承的类(具有属性不变性),并且还想添加一些新方法。像这样 ...但是正确防止将新属性分配给新类。
从namedtuple继承时,应定义__new__并设置__slots__为空元组(以保持不变性):
def define_new(clz):
def __new(cls, *args, **kwargs):
return super(clz, cls).__new__(cls, *args, **kwargs)
clz.__new__ = staticmethod(__new) # delegate namedtuple.__new__ to namedtuple
return clz
@define_new
class C(namedtuple('Foo', "a b c")):
__slots__ = () # Prevent assignment of new vars
def foo(self): return "foo"
C(1,2,3).x = 123 # Fails, correctly
Run Code Online (Sandbox Code Playgroud)
太好了 但是现在我想将__slots__任务移到装饰器中:
def define_new(clz):
def __new(cls, *args, **kwargs):
return super(clz, cls).__new__(cls, *args, **kwargs)
#clz.__slots__ = ()
clz.__slots__ = (123) # just for testing
clz.__new__ …Run Code Online (Sandbox Code Playgroud) 如何创建一个特殊的方法__repr__,我可以打印,例如,'6 of spades'还是'Q of diamonds'?
如何访问从数据namedtuple,牢记我有一个list的namedtuple以s self._cards?
import collections
cards = collections.namedtuple('Card', ['rank', 'suit'])
class Deck:
ranks = [str(n) for n in range (2,11)] + list('JQKA')
suits = 'spades diamonds hearts clubs'.split()
def __init__(self):
self._cards = [cards(rank, suit) for suit in self.suits for rank in self.ranks]
def __len__(self):
return len(self._cards)
def __getitem__(self, item):
return self._cards[item]
def __repr__(self):
return '%s of %s' % () # <-- don't know …Run Code Online (Sandbox Code Playgroud) 我有一个typing.NamedTuple我想转换为一个,dict以便我可以通过字典解包传递给一个函数:
def kwarg_func(**kwargs) -> None:
print(kwargs)
# This doesn't actually work, I am looking for something like this
kwarg_func(**dict(my_named_tuple))
Run Code Online (Sandbox Code Playgroud)
实现这一目标的最 Pythonic 方法是什么?我正在使用 Python 3.8+。
更多细节
这是一个NamedTuple可以使用的示例:
from typing import NamedTuple
class Foo(NamedTuple):
f: float
b: bool = True
foo = Foo(1.0)
Run Code Online (Sandbox Code Playgroud)
尝试kwarg_func(**dict(foo))提出一个TypeError:
TypeError: cannot convert dictionary update sequence element #0 to a sequence
Run Code Online (Sandbox Code Playgroud)
根据这篇文章collections.namedtuple,_asdict()作品:
TypeError: cannot convert dictionary update sequence element #0 to a sequence …Run Code Online (Sandbox Code Playgroud) namedtuple ×13
python ×12
python-3.x ×3
arrays ×1
class-method ×1
dataframe ×1
decorator ×1
dictionary ×1
inheritance ×1
list ×1
pandas ×1
pickle ×1
repr ×1
tuples ×1