Python 如何创建与调用的类不同的类?

Python 如何创建与调用的类不同的类?,python,class,warnings,Python,Class,Warnings,嗯。我一直在苦苦思索这个问题的措辞。 我有一个子类。我想让它创建一个基类的实例,如果调用它时某些事情是真的。我会用新的吗?如果是的话,我该怎么办 这是我的意思的一个例子: import warnings class A: def __init__(self, *args): self.val = list(args) def __str__(self): return "A" class B(A): def __init__(self,

嗯。我一直在苦苦思索这个问题的措辞。 我有一个子类。我想让它创建一个基类的实例,如果调用它时某些事情是真的。我会用新的吗?如果是的话,我该怎么办

这是我的意思的一个例子:

import warnings
class A:
    def __init__(self, *args):
        self.val = list(args)
    def __str__(self):
        return "A"

class B(A):
    def __init__(self, *args):
        if len(args)==3:
           A.__init__(self, *args)
           return
        else:
            warnings.warn("Making an A object!")
            return A(*args)

    def __str__(self):
        return "B"
    def extramethod1(self):
        print "This method is only in a B object"

x = B(1, 2, 3)
Warning (from warnings module)
  File '/test.py', line 14
UserWarning: Making an A object!
y = B(1, 2)
print x, y
'A B'
y.extramethod1()
'This method is only in a B object'

另外,当B执行此操作时,我如何让它发出警告?

\uuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu!不是目标

您可以尝试另一种方法:

def f(*largs,**kwargs):
    if (...):
        return A(*largs,**kwargs)
    return B(*largs,**kwargs)

x = f(1,2,3) 
y = f(1,2)  

您最终可以将f设为B的staticmethod,以便将其绑定到类

请参见。这是一个相反的问题:一个超类是否应该返回一个子类实例。答案是一样的:改用工厂函数。

不管您这样做的动机是什么,在Python中,每当您调用创建类实例时,我们称之为:

类的元类上的
\u调用\u
方法。这通常是“
类型.\uuuuu调用\uuuuu
——很少使用自定义元类来覆盖它

该函数依次调用该类的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
对象。(包括
None
,当人们忘记在
\uuuuu new\uuuu
方法中包含正确的
return
语句时,经常会发生这种情况。元类的
\uu call\uuuuuuu
调用新对象上的
\uuuu init\uuu
方法


出于您的目的,最简单的方法就是编写
\uuuuu new\uuuuu
方法,并使其返回您认为更合适的值。请注意,
\uuuuu init\uuuu
的返回值总是被忽略(因此应该是隐式的
None
,以免误导任何人阅读代码).

B的构造函数在哪里?你应该在那里定义init逻辑。可能的重复不是在生成一个A对象!你两次都生成了一个B对象。工厂在这种情况下是常见的,也是意料之中的。同样,如果有类似
my_instance=B(1,2,3)
的代码,然后调用
isinstance(my_instance,B)
并查看答案
False
!!