标签: python-attrs

如何避免__init__中的"self.x = x; self.y = y; self.z = z"模式?

我看到像这样的模式

def __init__(self, x, y, z):
    ...
    self.x = x
    self.y = y
    self.z = z
    ...
Run Code Online (Sandbox Code Playgroud)

经常使用更多参数.有没有一种好方法可以避免这种乏味的重复性?该类应该继承namedtuple吗?

python namedtuple python-2.7 python-decorators python-attrs

169
推荐指数
10
解决办法
1万
查看次数

在 __init__ 中为用户类设置默认/空属性

我有不错的编程水平,并从这里的社区中获得了很多价值。然而,我从来没有在编程方面进行过太多的学术教学,也没有与真正有经验的程序员一起工作。因此,我有时会为“最佳实践”而苦恼。

对于这个问题,我找不到更好的地方,尽管可能有讨厌这些问题的喷子,我还是发布了这个。如果这让你感到不安,很抱歉。我只是想学习,而不是惹你生气。

题:

当我创建一个新类时,我是否应该在init 中设置所有实例属性,即使它们是 None 并且实际上后来在类方法中分配了值?

MyClass 的属性结果见下例:

class MyClass:
    def __init__(self,df):
          self.df = df
          self.results = None

    def results(df_results):
         #Imagine some calculations here or something
         self.results = df_results
Run Code Online (Sandbox Code Playgroud)

我在其他项目中发现,当类属性只出现在类方法中时,它们可能会被埋没,而且还有很多事情要做。

那么对于经验丰富的专业程序员来说,什么是标准做法呢?为了可读性,您会在init 中定义所有实例属性吗?

如果有人有任何关于我可以在哪里找到这些原则的材料的链接,那么请将它们放在答案中,我们将不胜感激。我知道 PEP-8 并且已经在上面搜索了我的问题好几次,但找不到任何涉及此问题的人。

谢谢

安迪

python class instance-variables instance python-attrs

19
推荐指数
2
解决办法
2万
查看次数

如何在asdict中获取@property方法?

我有类似的东西:

from attr import attrs, attrib

@attrs
class Foo():
    max_count = attrib()
    @property
    def get_max_plus_one(self):
         return self.max_count + 1
Run Code Online (Sandbox Code Playgroud)

现在当我这样做时:

f = Foo(max_count=2)
f.get_max_plus_one =>3
Run Code Online (Sandbox Code Playgroud)

我想将其转换为字典:

{'max_count':2, 'get_max_plus_one': 3}
Run Code Online (Sandbox Code Playgroud)

当我使用时,attr.asdict(f)我没有得到@property. 我只得到 {'max_count':2}.

实现上述目标的最干净的方法是什么?

python python-attrs

10
推荐指数
1
解决办法
1515
查看次数

完美转发 - 在Python中

我是一个大量使用继承的Python项目的维护者.有一种反模式导致了我们一些问题并使阅读变得困难,我正在寻找一种解决它的好方法.

问题是将非常长的参数列表从派生类转发到基类 - 大多数但并不总是在构造函数中.

考虑这个人为的例子:

class Base(object):
    def __init__(self, a=1, b=2, c=3, d=4, e=5, f=6, g=7):
       self.a = a
       # etc

class DerivedA(Base):
    def __init__(self, a=1, b=2, c=300, d=4, e=5, f=6, g=700, z=0):
        super().__init__(a=a, b=b, c=c, d=d, e=e, f=f, g=g)
        self.z = z

class DerivedB(Base):
    def __init__(self, z=0, c=300, g=700, **kwds):
        super().__init__(c=c, g=g, **kwds)
        self.z = z
Run Code Online (Sandbox Code Playgroud)

此时,一切看起来都像DerivedA- 长参数列表,所有这些都明确地传递给基类.

不幸的是,我们在过去几年中遇到了一些问题,包括忘记传递参数并获取默认值,以及没有注意到一个派生类中的一个默认参数与默认默认值不同.

它还使代码不必要地笨重,因此难以阅读.

DerivedB是更好并修复这些问题,但有一个新的问题,派生类中的方法的Python帮助/ sphinx HTML文档是误导,因为很多重要的参数都隐藏在**kwds.

有没有办法将正确的签名 - 或者至少是正确签名的文档 - 从基类方法转发到派生类方法?

python python-attrs

8
推荐指数
1
解决办法
1804
查看次数

如何指定属性必须是(比方说)整数列表,而不仅仅是列表?

使用attrs libary和Python 3.6,我认为以下内容允许我指定它x并且y只能包含整数:

import attr

@attr.s
class C:
  x : List[int] = attr.ib()   # not working
  y = attr.ib(type=List[int]) # not working either
Run Code Online (Sandbox Code Playgroud)

两个评论的行都抛出了NameError: name 'List' is not defined.

我期望这样做的原因是:

(1)attr文档类型部分包括以下段落:" attrs还允许您使用类型参数与attr.ib()或 - 从Python 3.6开始 - 使用PEP 526-annotations将类型与属性相关联" .然后它演示了两种方法:

@attr.s
class C:
    x = attr.ib(type=int)
    y: int = attr.ib()
Run Code Online (Sandbox Code Playgroud)

(2)PEP 526声明类型注释的以下语法有效:primes: List[int] = [].

python types python-3.x python-attrs

7
推荐指数
1
解决办法
489
查看次数

使用attrs的子类上的Pycharm typehint

Pycharm抱怨MyClass实例的意外参数.有没有解决的办法?

import attr

@attr.s
class _Super:
    """ My Super class"""
    x: str = attr.ib(validator=attr.validators.instance_of(str))

@attr.s
class MyClass(_Super):
    """ My Sub class"""
    y:str = attr.ib(validator=attr.validators.instance_of(str))

x = MyClass(x="a", y="b")  # (x variable) Pycharm Typehint: "Unexpected argument"
Run Code Online (Sandbox Code Playgroud)

pycharm python-attrs

7
推荐指数
1
解决办法
256
查看次数

如何用字符串表示反序列化枚举?

我想创建一个类,它有一个枚举作为属性。此枚举应具有字符串表示形式,在将使用枚举属性的类实例转储为 JSON 字符串时,该表示形式显示为人类可读的值。在下面的最小工作示例中,我以三种不同的方式创建了三个枚举。

反序列化后,每个属性都向我们表明它来自枚举,但带有字符串表示形式的枚举除外。它只是一个字符串。

如果不可能实现这样的结构,我想知道为什么。

要求

如果你想测试它,你必须安装jsonsattrs使用

pip install attrs jsons
Run Code Online (Sandbox Code Playgroud)

最小工作示例

在这里您可以看到一个最小的工作示例。

import jsons
import attr

from enum import Enum

# ----------------------------------------------------
# create enumeration with the help of a dictionary

fruits = {
    "PINEAPPLE": "PINEAPPLE",
    "APPLE": "APPLE",
    "ORANGE": "ORANGE",
    "BANANA": "BANANA",
}

Fruit = Enum("FRUITS", fruits)

# ----------------------------------------------------
# create a classical enumeration


class Nut(Enum):

    PEANUT = 1
    HAZELNUT = 2
    CASHEW = 3
    WALNUT = 4


# ----------------------------------------------------
# create enumeration with a …
Run Code Online (Sandbox Code Playgroud)

python enums serialization json-deserialization python-attrs

7
推荐指数
1
解决办法
4571
查看次数

何时以及为什么要使用attr.Factory?

当我为什么要使用attr.ib(default=attr.Factory(list))attr.ib(default=[])

文档中我看到Factory用于生成一个新值,如果你使用带输入的lambda表达式,这是有意义的; 但是,如果您只是生成一个空列表,我不明白为什么要使用它.

我在这里错过了什么?

python python-3.x python-attrs

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

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
查看次数

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
查看次数