python - 为什么在Python类的__init__中使用self.foo = self.foo?

标签 python python-3.x networkx

我多次看到人们在他们的 init 函数中编写以下内容。

def __init__(self,**attr):
 self.foo = self.foo


这是一个(有用的)技巧吗? 有人可以向我解释一下吗?谢谢。

已更新。

例如,在networkx中的graph.py(用于定义Graph类)中 我看到以下内容。

def __init__(self, incoming_graph_data=None, **attr):
 self.graph_attr_dict_factory = self.graph_attr_dict_factory
 self.node_dict_factory = self.node_dict_factory
 

最佳答案

通过更多的代码,它的使用可能在两种不同的情况下有意义,尽管它仍然并不总是实现其所实现的目标的最佳方法:

class MyClass:
    baz = 1

    def __init__(self):
        self.baz = self.baz
        self._foo = None
        self.bar = None
        self.foo = self.foo

    @property
    def foo(self):
        if self._foo is None:
            self._foo = 1
        return self._foo

    @foo.setter
    def foo(self, value):
        self.bar = 0
        self._foo = value


m1 = MyClass()
m2 = MyClass()
print(m1.foo, m1.bar, m1.baz)
m1.baz = 2
MyClass.baz = 3
print(m1.baz, m2.baz, MyClass.baz)

有点做作,但是 self.foo = self.foo 将实现的是 .foo 属性的 getter 和 setter 都将被调用。

人们说 .foo 此时无法访问并且会引发 AttributeError 在您共享的有限情况下是正确的,但是定义属性当然会使它也可以在构造函数中使用,如此处的示例所示。我通过首先定义 ._foo 使代码更加简洁,但是当然您可以先在 setter 中定义它,但不建议这样做。

如果 setter 和 getter 有副作用,那么它们的运行就非常重要,这是使用属性的原因之一(另一个常见原因是您想要限制访问或限制可能的值)。

编辑:networkx 中的示例是将类属性重新分配给实例属性(在尝试之前我不知道它有效)。请参阅我的示例中最终 print() 的结果:

m1.baz = 2
MyClass.baz = 3
print(m1.baz, m2.baz, MyClass.baz)

结果:

2 1 3

networkx 这样做的原因可能是允许您提供不同的图形工厂方法,而不影响类 - 只有当您分配给它的 时,您的实例才会获得一个新的方法graph_attr_dict_factory,但它是使用类工厂方法初始化的。

但是,请注意,即使 networkx 没有像构造函数中那样进行设置,用户仍然可以稍后为实例分配一个新工厂并看到相同的行为 - 唯一真正的行为不同之处在于,到目前为止,实例不具有实例属性,而是会访问类属性。其他代码可能依赖于这种区别,因此删除赋值可能会对其他地方产生影响,但它对于类本身的直接功能没有任何作用。

关于python - 为什么在Python类的__init__中使用self.foo = self.foo?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71551468/

相关文章:

python - 如何拥有多个工具栏

java - Jython 图形库

python - 如何从 NetworkX 图转换为 ete3 Tree 对象?

python - numpy 的索引在这种情况下如何工作

python - 如何在seaborn lineplot上显示置信区间(误差带)

python - MongoDB/PyMongo : BadValue Unsupported projection option when trying to query all dates after

python - 使用命令提示符时如何将 Python 脚本输出保存到文件?

python-3.x - Spyder 控制台找不到 keras 模块

python - 如何检查两个节点是否连接?

python - 使用 Python Flask 将数据从 GET 请求传递到 POST 请求