Python 而是在调用类的创建时创建一个子类,这取决于某些逻辑

Python 而是在调用类的创建时创建一个子类,这取决于某些逻辑,python,class,instance,subclass,magic-square,Python,Class,Instance,Subclass,Magic Square,我最初发布的问题是缺少的,所以这里有一个解释,我希望它能让每个人都满意,并取消我收到的一些反对票 我希望在一个类中有一个智能,即创建一个实例后,根据某种逻辑,该实例将属于另一个类,它是这个类的子类之一 更具体地说,我正在制作一个解算器作为学习练习,并且: 我想要一个包含MagicSquare逻辑的MagicSquare类 我想拥有该类的OddMagicSquare和evenmimagicsquare子类,它们将包含求解这两类幻方的逻辑 我希望能够调用MagicSquare的创建,提供它的大小,

我最初发布的问题是缺少的,所以这里有一个解释,我希望它能让每个人都满意,并取消我收到的一些反对票

我希望在一个类中有一个智能,即创建一个实例后,根据某种逻辑,该实例将属于另一个类,它是这个类的子类之一

更具体地说,我正在制作一个解算器作为学习练习,并且:

  • 我想要一个包含MagicSquare逻辑的
    MagicSquare
  • 我想拥有该类的
    OddMagicSquare
    evenmimagicsquare
    子类,它们将包含求解这两类幻方的逻辑
  • 我希望能够调用
    MagicSquare
    的创建,提供它的大小,
    n
    ,并让
    MagicSquare
    中的智能确定要创建实例的子类,而不是泛型的顶级类
    MagicSquare

我知道,在
MagicSquare
之外,可以(如果可能的话,可能更容易实现)智能地确定创建实例的子类(
OddMagicSquare
/
甚至MagicSquare
)是。我想把它放在MagicSquare里面的原因可能是直觉。我有一种预感,这样做会更干净整洁,因为在我看来,确定某个幻方是哪种幻方的逻辑似乎属于
MagicSquare
类。

最初,我提供了一个基于在
\uu init\uuu()
期间改变
自我的答案。评论中向我解释说,这应该避免

现在,我提供了一个基于重新定义基类“
\uuuu new\uuuu
”的答案:

class Car(object):
    """The base class."""

    def __new__(cls, max_speed):
        if cls is Car and max_speed > 100:
            return object.__new__(SuperCar, max_speed)
        else:
            return object.__new__(cls, max_speed)

    def __init__(self, max_speed):
        self.max_speed = max_speed

class SuperCar(Car):
    """The sub class."""

    pass   
负责创建实例的代码位于内置的(1)
\uuuuu new\uuuu
方法中。当调用一个类(例如,
my_car=car(100)
)并传递该调用中给出的参数时,就会调用它

调用
汽车
超级汽车
(由于继承了
\uuuuu新的
)的实例时,重新定义的
\uu新的
检查要创建的实例是否为
cls
汽车
,并且
最大速度
大于100

如果是这样,它将使用
对象创建一个
超级跑车
的实例,而不是
汽车
。\uuuuuuu新的(超级跑车,最高速度)
,并返回该实例

否则,它使用
对象调用普通、默认、内置的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。这捕获了
而不是max_speed>100
的预期情况,以及子类
超级跑车调用此重新定义的
\uuuuuuuuuuuuu
的情况(如
我的法拉利=超级跑车(250)

为了记录在案,我以前的回答是:

当您希望将实例的类更改为其 子类,取决于某些条件,在创建时 例如,您可以在
\uuuu init\uuuu
中使用一些逻辑,如下所示:

class Car(object):
    def __init__(self, max_speed_kph):
        if self.__class__ == Car:
            if max_speed_kph > 230:
                self.__class__ = SuperCar
                self.__init__()

class SuperCar(Car):
    def __init__(self):
        print 'this car is fast!'
self.\uuuu init\uuuu()
用于重新初始化实例 新班级

脚注:

  • 这真的是内置的吗?我在Python文档的“内置函数”主题中看不到它

  • 最初,我提供了一个答案,这个答案是基于在
    \uuuuu init\uuuuuu()
    期间更改
    self.\uuuuu class\uuuuuuuu
    。评论中向我解释说,这应该避免

    现在,我提供了一个基于重新定义基类“
    \uuuu new\uuuu
    ”的答案:

    class Car(object):
        """The base class."""
    
        def __new__(cls, max_speed):
            if cls is Car and max_speed > 100:
                return object.__new__(SuperCar, max_speed)
            else:
                return object.__new__(cls, max_speed)
    
        def __init__(self, max_speed):
            self.max_speed = max_speed
    
    class SuperCar(Car):
        """The sub class."""
    
        pass   
    
    负责创建实例的代码位于内置的(1)
    \uuuuu new\uuuu
    方法中。当调用一个类(例如,
    my_car=car(100)
    )并传递该调用中给出的参数时,就会调用它

    调用
    汽车
    超级汽车
    (由于继承了
    \uuuuu新的
    )的实例时,重新定义的
    \uu新的
    检查要创建的实例是否为
    cls
    汽车
    ,并且
    最大速度
    大于100

    如果是这样,它将使用
    对象创建一个
    超级跑车
    的实例,而不是
    汽车
    。\uuuuuuu新的(超级跑车,最高速度)
    ,并返回该实例

    否则,它使用
    对象调用普通、默认、内置的
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。这捕获了
    而不是max_speed>100
    的预期情况,以及子类
    超级跑车调用此重新定义的
    \uuuuuuuuuuuuu
    的情况(如
    我的法拉利=超级跑车(250)

    为了记录在案,我以前的回答是:

    当您希望将实例的类更改为其 子类,取决于某些条件,在创建时 例如,您可以在
    \uuuu init\uuuu
    中使用一些逻辑,如下所示:

    class Car(object):
        def __init__(self, max_speed_kph):
            if self.__class__ == Car:
                if max_speed_kph > 230:
                    self.__class__ = SuperCar
                    self.__init__()
    
    class SuperCar(Car):
        def __init__(self):
            print 'this car is fast!'
    
    self.\uuuu init\uuuu()
    用于重新初始化实例 新班级

    脚注:

  • 这真的是内置的吗?我在Python文档的“内置函数”主题中看不到它

  • 并非每件事都必须是一门课。

    为什么不使用工厂功能

    class Car(object):
    ....
    
    class SuperCar(Car):
    ....
    
    def CarFactory(max_speed):
         if max_speed > 100:
             return SuperCar()
         else: 
             return Car()
    

    并非每件事都必须是一门课。

    为什么不使用工厂功能

    class Car(object):
    ....
    
    class SuperCar(Car):
    ....
    
    def CarFactory(max_speed):
         if max_speed > 100:
             return SuperCar()
         else: 
             return Car()
    

    首先,由于您没有给出示例,下面是我们熟悉的玩具最小类层次结构:

    class Base(object):
        def __init__(self):
            print("I'm a base")
    
    class Child(Base):
        def __init__(self):
            super(Child, self).__init__()
            print("I'm also a child")
    

    现在,你想决定是不是一个<代码>子< /代码>在中间,还是在后面, Base. 最好的

    class Base(object):
        def __init__(self, child=False):
            super(Base, self).__init__()
            if child:
                self.__class__ = Child
    
    class MagicSquareSolver(metaclass=abc.ABCMeta:
        def __init__(self, square):
            self.square = square
        @abc.abstractmethod
        def solve(self):
            pass
    
    class OddMagicSquareSolver(MagicSquareSolver):
        def __init__(self, square):
            super().__init__(square)
            do_odd_specific_stuff(self)
        def solve(self):
            do_odd_specific_solution(self)
    
    class EvenMagicSquareSolver(MagicSquareSolver):
        def __init__(self, square):
            super().__init__(square)
            do_even_specific_stuff(self)
        def solve(self):
            do_even_specific_solution(self)
    
    class MagicSquare:
        def __init__(self, n):
            self.n = n
            self.cells = self.make_cells()
            if n % 2:
                self.solver = OddMagicSquareSolver(self)
            else:
                self.solver = EvenMagicSquareSolver(self)
        def solve(self):
            return self.solver.solve()
    
    class MagicSquare:
        def __init__(self, n):
            self.n = n
            self.fill_squares()
            self.cells = self.make_cells()
        def solve(self):
            if n % 2:
                return self._solve_odd()
            else:
                return self._solve_even()
        def _solve_odd(self):
            stuff()
        def _solve_even(self):
            other_stuff()