我很好奇如何将attrs与抽象类结合起来。我想定义一个抽象类,它定义每个继承类必须具有的抽象属性。
我想对这个继承类使用 attrs 来定义它的属性。所以我尝试两者都玩一点:
import abc
import attr
class Parent(object):
__metaclass__ = abc.ABCMeta
@abc.abstractproperty
def x(self):
pass
@attr.s()
class Child(Parent):
x = attr.ib()
c = Child(9)
c.x = 7
Run Code Online (Sandbox Code Playgroud)
引发以下错误:
AttributeError: can't set attribute
Run Code Online (Sandbox Code Playgroud)
也许有一种方法可以使用 attrs 将属性声明为抽象属性?:
@attr.s()
class Parent(object):
__metaclass__ = abc.ABCMeta
x = attr.ib(abstract=True)
Run Code Online (Sandbox Code Playgroud)
如果有人找到一种更好的方法来获得这两个模块的好处,我将非常感激!
提前谢谢了!
我的课程看起来像这样:
@attr.s
class ImageMagic(object):
path = attr.ib()
_img = attr.ib()
@_img.default
def _img(self):
return Image.open(self.path)
@attr.s
class FileObject(object):
# Standard
path = attr.ib()
# When magic-ed
magic = attr.ib(default=None)
Run Code Online (Sandbox Code Playgroud)
我的目标是让 attrs.asdict() 能够FileObject通过遍历所有 attrs 并仅在实际调用序列化而不是在调用时初始化 magic 属性来序列化__init__。
大多数时候我真的不希望 Magic 库检查对象,因为这是一个昂贵的 IO 操作。
目标:
a) 如何连接两个类
b)具有 magic 属性,仅在我实际调用 ImageMagic 对象时实例化它。
c) 仅一次,以便以后多次调用时可以重复使用。
有了这个,我更愿意使用 Attrs 库。
一般不干净的解决方案是使用一个@property带有 getter 的 getter,getter 检查私有属性是否存在_magic,如果不存在则加载。
然后以某种方式将属性注册到 attrs 库,以便它可以进一步序列化。
这是实际解决方案的示例:
@attr.s
class IOExpensiveClass(object):
path = attr.ib()
_hash = attr.ib() …Run Code Online (Sandbox Code Playgroud) 所以我喜欢使用 attr 但有时我需要做我自己的事情。我可以__init__用自己的方法覆盖该方法吗?
import attr
@attr.s(auto_attribs=True)
class MyClass:
i: int
def __init__(self, i, special=None):
if special:
self.i = special
else:
self.i = i
>>> a = MyClass(i=1,special=2)
Traceback (most recent call last):
File "<input>", line 1, in <module>
a = MyClass(i=1,special=2)
TypeError: __init__() got an unexpected keyword argument 'special'
Run Code Online (Sandbox Code Playgroud)
另一个例子:
@attr.s(auto_attribs=True)
class MyOtherClass:
i: int
def __init__(self, i, **kwargs):
self.i = kwargs.get('magic',i)
>>> a = MyOtherClass(i=5,magic=12)
Traceback (most recent call last):
File "<input>", line 1, in <module>
a …Run Code Online (Sandbox Code Playgroud) 是否有使用 attrs 转换器的装饰器?
有validator和的装饰器default,但我看不到任何提到的converter。
是否可以?
我更喜欢将该函数作为类内的“方法”,而不是类外的全局函数。装饰器允许这样做:)
验证器的示例片段。
payload : bytes = attr.ib( default=b'', on_setattr=attr.setters.validate )
#! NOTE: using attrs validator as a property setter function.
@payload.validator
def payload_setter( self, attribute : attr.Attribute, value : bytes ) -> None :
self.payload_length = len( value )
Run Code Online (Sandbox Code Playgroud)
我想使用转换器做类似的事情。将某些输入字节修剪到上限的示例。
data : bytes = attr.ib( default=b'', on_setattr=attr.setters.converter )
#! NOTE: using attrs converter as a property setter function.
@data.converter
def data_setter( self, attribute : attr.Attribute, value : bytes ) …Run Code Online (Sandbox Code Playgroud) 我正在使用attrspython 包,结合继承和插槽。我想从派生方法中调用父类的方法。该问题演示如下:
import attr
@attr.s(slots=True)
class Base():
def meth(self):
print("hello")
@attr.s(slots=True)
class Derived(Base):
def meth(self):
super().meth()
print("world")
d = Derived()
d.meth()
Run Code Online (Sandbox Code Playgroud)
我得到:
TypeError: super(type, obj): obj 必须是 type 的实例或子类型
__slots__=()该问题似乎是由 attrs(具有显式工作的未修饰类)、插槽(常规@attr.s修饰类工作)和普通super()调用(工作)的组合触发的super(Derived, self)。
我想了解super()与显式super(Derived, self)版本的行为有何不同,因为文档说它们“做同样的事情”
当我想使用 attr 库忽略某些字段时,我可以使用repr=Falseoption.
但我在 pydantic 中找不到类似的选项
请参阅示例代码
import typing
import attr
from pydantic import BaseModel
@attr.s(auto_attribs=True)
class AttrTemp:
foo: typing.Any
boo: typing.Any = attr.ib(repr=False)
class Temp(BaseModel):
foo: typing.Any
boo: typing.Any # I don't want to print
class Config:
frozen = True
a = Temp(
foo="test",
boo="test",
)
b = AttrTemp(foo="test", boo="test")
print(a) # foo='test' boo='test'
print(b) # AttrTemp(foo='test')
Run Code Online (Sandbox Code Playgroud)
但是,这并不意味着根本没有选项,我可以使用语法print(a.dict(exclude={"boo"}))
pydantic 没有类似的选项吗repr=False?
我想用Python来创建JSON.
既然我找不到可以帮助我的库,我想知道是否可以检查Python文件中类的顺序?
例
# example.py
class Foo:
pass
class Bar:
pass
Run Code Online (Sandbox Code Playgroud)
如果我导入example,我想知道类的顺序.在这种情况下,它是[Foo,Bar]而不是[Bar,Foo].
这可能吗?如果"是",怎么样?
我对yaml/json不满意.我有一个模糊的想法是通过Python类创建配置(只有类,而不是对象的实例化).
欢迎使用能够帮助我实现目标的答案(使用简单有趣的工具创建JSON).
前言
\n\n我想知道如何以Python方式概念化数据类。\n特别是我\xe2\x80\x99m 谈论 DTO(数据传输对象)。
\n\n我在 @jeff-oneill 问题 \xe2\x80\x9c使用 Python 类作为数据容器\xe2\x80\x9d 中找到了一个很好的答案,其中 @joe-kington 很好地使用了内置namedtuple.
问题
\n\n在 python 2.7 文档的第 8.3.4 节中,有一个关于如何组合多个命名元组的很好的示例。\n我的问题是如何实现相反的效果?
\n\n例子
\n\n考虑文档中的示例:
\n\n>>> p._fields # view the field names\n(\'x\', \'y\')\n\n>>> Color = namedtuple(\'Color\', \'red green blue\')\n>>> Pixel = namedtuple(\'Pixel\', Point._fields + Color._fields)\n>>> Pixel(11, 22, 128, 255, 0)\nPixel(x=11, y=22, red=128, green=255, blue=0)\nRun Code Online (Sandbox Code Playgroud)\n\n如何从 \xe2\x80\x9cPixel\xe2\x80\x9d 实例推断出 \xe2\x80\x9cColor\xe2\x80\x9d 或 \xe2\x80\x9cPoint\xe2\x80\x9d 实例?
\n\n最好是具有蟒蛇精神。 …
我有几个使用 attrs 定义的类,如下所示:
from attr import attrs, attrib, validators
@attrs
class MyClass:
name = attrib(])
@name.validator
def check_length(self, attribute, value):
if not (3 <= len(value) <= 30):
raise ValueError("Name must be between 3 and 30 characters")
description = attrib()
@description.validator
def check_length(self, attribute, value):
if not (10 <= len(value) <= 400):
raise ValueError("Description must be between 10 and 400 characters")
Run Code Online (Sandbox Code Playgroud)
对于几个属性,我需要创建一个验证器来检查数据是否在某个范围内。我想避免重复,所以我可以创建一个自定义验证器,在其中传递一些额外的最小值和最大值参数,如下所示:
def range_validator(instance, attribute, value, min_value, max_value):
if min_value >= len(value) >= max_value:
raise ValueError("Must be between {} and {}".format(min_value, …Run Code Online (Sandbox Code Playgroud) 我遇到的情况是 attrs 类继承自另一个类,该类的属性具有默认值。这会引发 ValueError。
这是一个例子:
from attrs import define
@define
class A:
a: int = 1
@define
class B(A):
b: int
test = B(b=1)
>>> ValueError: No mandatory attributes allowed after an attribute with a default value or factory. Attribute in question: Attribute(name='b', ...
Run Code Online (Sandbox Code Playgroud)
我该如何避免这种行为?
python-attrs ×10
python ×9
python-3.x ×3
dto ×1
namedtuple ×1
pydantic ×1
python-2.7 ×1
python-3.7 ×1
super ×1