标签: python-attrs

Python - attrs类继承自抽象类

我很好奇如何将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)

如果有人找到一种更好的方法来获得这两个模块的好处,我将非常感激!

提前谢谢了!

python python-attrs

5
推荐指数
1
解决办法
5313
查看次数

Python attrs 类属性缓存延迟加载

我的课程看起来像这样:

@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)

python python-attrs

5
推荐指数
1
解决办法
1184
查看次数

在 python attrs 类中,如何用我自己的重写生成的 __init__

所以我喜欢使用 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)

python python-3.7 python-attrs

5
推荐指数
1
解决办法
5866
查看次数

attrs 转换器的装饰器

是否有使用 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)

python-attrs

5
推荐指数
1
解决办法
1714
查看次数

super() 和显式 super(Cl,self) (带有 __slots__ 和 attrs)有什么区别

我正在使用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)版本的行为有何不同,因为文档说它们“做同样的事情”

python super python-3.x python-attrs

4
推荐指数
1
解决办法
411
查看次数

如何忽略 pydantic 中的字段 repr?

当我想使用 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 python-3.x python-attrs pydantic

4
推荐指数
1
解决办法
6051
查看次数

使用Python创建JSON

我想用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).

python configuration introspection python-attrs

3
推荐指数
1
解决办法
689
查看次数

如何从另一个命名元组推导或子类型命名元组?

前言

\n\n

我想知道如何以Python方式概念化数据类。\n特别是我\xe2\x80\x99m 谈论 DTO(数据传输对象)。

\n\n

我在 @jeff-oneill 问题 \xe2\x80\x9c使用 Python 类作为数据容器\xe2\x80\x9d 中找到了一个很好的答案,其中 @joe-kington 很好地使用了内置namedtuple.

\n\n

问题

\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)\n
Run 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

最好是具有蟒蛇精神。 …

python dto namedtuple python-2.7 python-attrs

3
推荐指数
1
解决办法
1159
查看次数

python-attrs 中带有额外参数的自定义验证器

我有几个使用 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)

python python-3.x python-attrs

3
推荐指数
1
解决办法
2160
查看次数

Python attrs:从具有默认值的类继承会引发错误

我遇到的情况是 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 python-attrs

3
推荐指数
1
解决办法
2830
查看次数