相关疑难解决方法(0)

__slots__的用法?

__slots__Python中的目的是什么- 特别是关于我何时想要使用它,何时不想使用它?

python oop slots python-internals

697
推荐指数
10
解决办法
18万
查看次数

Python(和Python C API):__ new__与__init__

我要问的问题似乎是Python使用__new__和__init__的重复但是无论如何,我还不清楚到底是什么__new____init__它之间的实际区别.

在你急于告诉我__new__是用于创建对象并且__init__用于初始化对象之前,让我说清楚:我明白了. 事实上,这种区别对我来说是很自然的,因为我在C++中有经验,我们有新的贴图,它同样将对象分配与初始化分开.

Python的C API教程解释它是这样的:

新成员负责创建(而不是初始化)该类型的对象.它在Python中作为__new__()方法公开.... 实现新方法的一个原因是确保实例变量的初始值.

所以,是的 - 我得到了什么__new__,但尽管如此,我仍然不明白为什么它在Python中有用.给出的示例说,__new__如果要"确保实例变量的初始值" ,这可能很有用.那么,这究竟是什么意思__init__呢?

在C API教程中,显示​​了一个示例,其中创建了一个新类型(称为"Noddy"),并__new__定义了Type的函数.Noddy类型包含一个名为的字符串成员first,并且此字符串成员初始化为空字符串,如下所示:

static PyObject * Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    .....

    self->first = PyString_FromString("");
    if (self->first == NULL)
    {
       Py_DECREF(self);
       return NULL;
    }

    .....
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果没有__new__此处定义的方法,我们必须使用PyType_GenericNew,它只是将所有实例变量成员初始化为NULL.因此,该__new__方法的唯一好处是实例变量将以空字符串开头,而不是NULL. 但是为什么这个有用,因为如果我们关心确保我们的实例变量被初始化为某个默认值,我们可以在 …

c python python-c-api

118
推荐指数
5
解决办法
3万
查看次数

Python中的__weakref__究竟是什么?

令人惊讶的是,没有明确的文档__weakref__.这里解释弱引用.__weakref__也很快在文档中提到__slots__.但我找不到任何关于__weakref__它自己的东西.

到底是__weakref__什么? - 它只是一个作为标志的成员:如果存在,该对象可能被弱引用? - 或者它是一个可以被覆盖/分配以获得所需行为的函数/变量?怎么样?

python python-3.x python-internals

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

Python中的Builder模式等效

在Java中,您可以使用构建器模式提供更具可读性的方法来实例化具有许多参数的类.在构建器模式中,构造一个配置对象,其中包含设置命名属性的方法,然后使用它来构造另一个对象.

Python中的等价物是什么?是模仿相同实现的最佳方法吗?

python design-patterns builder-pattern

47
推荐指数
5
解决办法
3万
查看次数

当Frozen = True时,如何在__post_init__中设置dataclass字段的值?

我正在尝试创建冻结的数据类,但在设置中的值时遇到问题__post_init__。有没有办法从设置基于值的字段值init paramdataclass使用时frozen=True设置?

RANKS = '2,3,4,5,6,7,8,9,10,J,Q,K,A'.split(',')
SUITS = 'H,D,C,S'.split(',')


@dataclass(order=True, frozen=True)
class Card:
    rank: str = field(compare=False)
    suit: str = field(compare=False)
    value: int = field(init=False)
    def __post_init__(self):
        self.value = RANKS.index(self.rank) + 1
    def __add__(self, other):
        if isinstance(other, Card):
            return self.value + other.value
        return self.value + other
    def __str__(self):
        return f'{self.rank} of {self.suit}'
Run Code Online (Sandbox Code Playgroud)

这就是痕迹

 File "C:/Users/user/.PyCharm2018.3/config/scratches/scratch_5.py", line 17, in __post_init__
    self.value = RANKS.index(self.rank) + 1
  File "<string>", line 3, in __setattr__
dataclasses.FrozenInstanceError: cannot assign …
Run Code Online (Sandbox Code Playgroud)

python

20
推荐指数
4
解决办法
1881
查看次数

如何在Python中使类不可变

我正在做一些分布式计算,其中几台机器在假设它们都具有不同类的相同版本的情况下进行通信.因此,使这些类不可变是一种好的设计; 不是因为它必须挫败一个意图不好的用户,只是不可改变的,它永远不会被意外修改.

我该怎么做?例如,我如何实现一个元类,使得类在定义后使用它是不可变的?

>>> class A(object):
...     __metaclass__ = ImmutableMetaclass
>>> A.something = SomethingElse # Don't want this
>>> a = A()
>>> a.something = Whatever # obviously, this is still perfectly fine.
Run Code Online (Sandbox Code Playgroud)

替代方法也很好,例如一个装饰器/函数,它接受一个类并返回一个不可变的类.

python metaclass immutability

16
推荐指数
2
解决办法
9335
查看次数

在运行时覆盖__setattr__

我试图覆盖__setattr__Python类的方法,因为每次实例属性更改其值时我都想调用另一个函数.但是,我不希望在该__init__方法中出现这种情况,因为在此初始化期间,我设置了一些稍后将使用的属性:

到目前为止,我有这个解决方案,而不是__setattr__在运行时覆盖:

class Foo(object):
    def __init__(self, a, host):
        object.__setattr__(self, 'a', a)
        object.__setattr__(self, 'b', b)
        result = self.process(a)
        for key, value in result.items():
            object.__setattr__(self, key, value)

    def __setattr__(self, name, value):
        print(self.b) # Call to a function using self.b
        object.__setattr__(self, name, value)
Run Code Online (Sandbox Code Playgroud)

但是,我想避免这些object.__setattr__(...)__setattr____init__方法结束时覆盖:

class Foo(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b
        result = self.process(a)
        for key, value in result.items():
            setattr(self, key, value)
        # override self.__setattr__ here …
Run Code Online (Sandbox Code Playgroud)

python

16
推荐指数
2
解决办法
3948
查看次数

为什么Python没有真正的常量?这不危险吗?

Python 3

我通过一本书学习Python.现在我了解到Python在这个意义上没有常量,它们在C++或C#中可用...例如,可以编写这样的危险代码:

>>> import math
>>> math.pi
3.141592653589793
>>> math.pi = 123.456
>>> math.pi
123.456
>>> 
Run Code Online (Sandbox Code Playgroud)

嗯......对我来说这是一个令人不快的惊喜......

即我可能没有受到保护,因为我加载到我的代码中的任何模块(不是我的)都可能损坏不会改变的数据.

为什么在Python中它是如此制作的?这不危险吗?

python

15
推荐指数
1
解决办法
599
查看次数

将可变对象锁定为python中的不可变对象

如何在Python中"锁定"对象?

说我有:

class Foo:
  def __init__(self):
    self.bar = []
    self.qnx = 10
Run Code Online (Sandbox Code Playgroud)

我会尽可能多地修改foo:

foo = Foo()
foo.bar.append('blah')
foo.qnx = 20
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试时,我希望能够"锁定"它

lock(foo)
foo.bar.append('blah')  # raises some exception.
foo.qnx = 20            # raises some exception.
Run Code Online (Sandbox Code Playgroud)

这可能在Python中吗?

python immutability

11
推荐指数
1
解决办法
398
查看次数

我可以在Python3中限制对象,以便只允许我创建setter的属性吗?

我有一个叫做Node的东西.定义和定理都是一种节点,但只允许定义具有plural属性:

class Definition(Node):


    def __init__(self,dic):
        self.type = "definition"
        super(Definition, self).__init__(dic)
        self.plural = move_attribute(dic, {'plural', 'pl'}, strict=False)


    @property
    def plural(self):
        return self._plural

    @plural.setter
    def plural(self, new_plural):
        if new_plural is None:
            self._plural = None
        else:
            clean_plural = check_type_and_clean(new_plural, str)
            assert dunderscore_count(clean_plural)>=2
            self._plural = clean_plural


class Theorem(Node):


    def __init__(self, dic):
        self.type = "theorem"
        super().__init__(dic)
        self.proofs = move_attribute(dic, {'proofs', 'proof'}, strict=False)
        # theorems CANNOT have plurals:
        # if 'plural' in self:
        #   raise KeyError('Theorems cannot have plurals.')
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,定义有一个plural.setter,但定理没有.但是,代码

theorem = …
Run Code Online (Sandbox Code Playgroud)

oop inheritance python-3.x

11
推荐指数
1
解决办法
211
查看次数