__slots__Python中的目的是什么- 特别是关于我何时想要使用它,何时不想使用它?
我要问的问题似乎是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. 但是为什么这个有用,因为如果我们关心确保我们的实例变量被初始化为某个默认值,我们可以在 …
在Java中,您可以使用构建器模式提供更具可读性的方法来实例化具有许多参数的类.在构建器模式中,构造一个配置对象,其中包含设置命名属性的方法,然后使用它来构造另一个对象.
Python中的等价物是什么?是模仿相同实现的最佳方法吗?
我正在尝试创建冻结的数据类,但在设置中的值时遇到问题__post_init__。有没有办法从设置基于值的字段值init param在dataclass使用时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) 我正在做一些分布式计算,其中几台机器在假设它们都具有不同类的相同版本的情况下进行通信.因此,使这些类不可变是一种好的设计; 不是因为它必须挫败一个意图不好的用户,只是不可改变的,它永远不会被意外修改.
我该怎么做?例如,我如何实现一个元类,使得类在定义后使用它是不可变的?
>>> 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)
替代方法也很好,例如一个装饰器/函数,它接受一个类并返回一个不可变的类.
我试图覆盖__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 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中"锁定"对象?
说我有:
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中吗?
我有一个叫做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) python ×9
immutability ×2
oop ×2
python-3.x ×2
c ×1
inheritance ×1
metaclass ×1
python-c-api ×1
slots ×1