python - 在 python 中从 __new__() 调用其他类方法

标签 python python-3.x class oop

我创建了一个类foo,如下所示:

class foo():

    def __new__(cls, a, b, c, add=True):
        return cls.sum(a, b, c) if add else cls.subtract(a, b, c)

    def sum(a, b, c):
        return a + b + c

    def subtract(a, b, c):
        return c - b - a

print(foo(1, 2, 3, True))

该程序返回所需的结果为6。但是,我需要澄清一些概念:

  1. 使用这种 OOP 方法或设计是否正确,或者是否有更好的方法?我希望类返回一个值或任何其他对象(不是它自己的类实例)
  2. 无论上面的结构如何,如果 sumsubtract 是实例方法,那么如何在不实例化对象的情况下调用它们,如上例所示,即 打印(...)

我观察到许多 python API 和框架通过类实例化返回对象或值。

我正在尝试理解Python中OOP的核心概念,请帮忙。

最佳答案

按照你现在的方式,sumsubtract确实是实例方法。

>>> foo_obj = object.__new__(foo)  # This will actually create a foo object to demonstrate
>>> foo_obj.sum
<bound method foo.sum of <__main__.foo object at 0x0000000000000000>>
>>> type(foo_obj.sum)
<class 'method'>

但这只是因为当您通过实例访问它们时,Python 会动态创建一个方法(基本上只是将第一个参数绑定(bind)到对象,通常是 self )

但是,您可以通过类访问包装的函数:

>>> foo_obj.sum.__func__
<function foo.sum at 0x0000000000000001>
>>> foo.sum
<function foo.sum at 0x0000000000000001>
>>> foo_obj.sum.__func__ is foo.sum
True

所以在你的 __new__ 中函数,它不会绑定(bind)第一个参数,并且它们调用底层函数而不是使它们成为实例方法。

要修复警告,您可以将它们设为 classmethod staticmethod s。但不返回 __new__ 中类实例的对象通常是不好的做法。 。如果您确实想使用 OOP,请子类 int或者制作一个包装,这样你就可以:

>>> class Foo:
    __slots__ = 'value',
    def __init__(self, a, b, c, add=True):
        self.value = self.sum(a, b, c) if add else self.subtract(a, b, c)
    @staticmethod
    def sum(a, b, c):
        return a + b + c
    @staticmethod
    def subtract(a, b, c):
        return c - b - a
>>> foo = Foo(1, 2, 3, True)
>>> foo
<__main__.foo object at 0x0000000000000002>
>>> foo.value
6

>>> class Foo(int):
    __slots__ = ()
    def __new__(cls, a, b, c, add=True):
        value = cls.sum(a, b, c) if add else cls.subtract(a, b, c)
        return super().__new__(cls, value)
    @staticmethod
    def sum(a, b, c):
        return a + b + c
    @staticmethod
    def subtract(a, b, c):
        return c - b - a
>>> foo = Foo(1, 2, 3, True)
>>> foo
6
>>> type(foo)
<class '__main__.Foo'>

关于python - 在 python 中从 __new__() 调用其他类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53023077/

相关文章:

python - 初始化 python ctypes 结构体字段的更好方法

python - 在python脚本中加载新安装的模块

python - 将整个单词下移索引

c++ - 触发了一个断点(析构函数),类模板类型是它自己的一个版本?

Java内置类到接口(interface)

python - 尝试/捕捉或验证速度?

python - 检查文件系统在 Python 中是否不区分大小写

python - dict.pop与dict.get的默认返回值

python - 为什么不能在没有额外的 `import` 语句的情况下引用似乎由解释器自动加载的模块?

javascript - 是否有 es-lint 或类似的规则来禁用 `extends`