简体   繁体   English

在python中从__new __()调用其他类方法

[英]Calling other class methods from __new__() in python

I have created a class foo as below: 我创建了一个如下所示的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))

This program returns the required result as 6 . 该程序返回所需结果为6 However, I needed to get the clarity of a few concepts: 但是,我需要弄清楚一些概念:

  1. Is using this methodology or design of OOP correct or is there a better way to do it? 使用这种方法或OOP设计是正确的还是有更好的方法呢? I want the class to return a value or any other object(not it's own class instance) 我希望类返回一个值或任何其他对象(不是它自己的类实例)
  2. Regardless of the structure above, if sum and subtract are instance methods, how can they be called without instantiating an object as in the above example ie, print(...) ? 不管上面的结构如何,如果sumsubtract是实例方法,那么如何在不实例化对象的情况下调用它们,如上述示例,即print(...)

I have observed many python APIs and frameworks returning an object or a value through class instantiation. 我观察到许多python API和框架通过类实例化返回对象或值。

I am trying to understand the core concepts of OOPs in python please help. 我想了解python中OOP的核心概念,请帮忙。

The way you have it now, sum and subtract are indeed instance methods. 您现在拥有的方式, 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'>

But that's just because when you access them through an instance, Python dynamically creates a method (Basically just binds the first argument to the object, usually self ) 但这仅仅是因为当您通过实例访问它们时,Python动态创建了一个方法(基本上只是将第一个参数绑定到对象,通常是self

But, you can access the wrapped function through the class: 但是,您可以通过该类访问包装的函数:

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

So in your __new__ function, it won't bind the first argument, and they call the underlying function instead of making them an instance method. 因此,在您的__new__函数中,它不会绑定第一个参数,并且它们将调用基础函数,而不是使它们成为实例方法。

To fix the warnings, you can make them classmethod s or staticmethod s. 要解决这些警告,可以将它们设置为classmethodstaticmethod But it is generally bad practice to not return an object that is an instance of the class from the __new__ . 但是,通常不建议不从__new__返回作为类实例的对象。 If you really wanted to use OOP, either subclass int or make a wrapper, so you can have: 如果您确实想使用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

or 要么

>>> 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'>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM