Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 超类中子类的自动初始化_Python_Class_Inheritance - Fatal编程技术网

Python 超类中子类的自动初始化

Python 超类中子类的自动初始化,python,class,inheritance,Python,Class,Inheritance,一个类似的问题也被问到了。那里的答案得出结论认为,应该避免这种做法,我不确定以下情况是否属实,我想知道如何实现这一点,或者我应该做些什么 class Rational(): 定义初始值(自身、分子、分母): self.momerator=分子 分母 如果self.densor==1: 通过 #TODO初始化为整数 # ... 有理数的更多方法 类整数(有理): 定义初始值(自身,值): 超级() 自我价值=价值 # ... 整数的更多方法 在这个文件中,我有一些简单的整数类和有理数类。由于所有

一个类似的问题也被问到了。那里的答案得出结论认为,应该避免这种做法,我不确定以下情况是否属实,我想知道如何实现这一点,或者我应该做些什么

class Rational():
定义初始值(自身、分子、分母):
self.momerator=分子
分母
如果self.densor==1:
通过
#TODO初始化为整数
# ... 有理数的更多方法
类整数(有理):
定义初始值(自身,值):
超级()
自我价值=价值
# ... 整数的更多方法
在这个文件中,我有一些简单的整数类和有理数类。由于所有的
Integer
都是有理数,
Integer
是rational的一个子类,我们调用
super()
来允许整数调用有理数的方法

不过,如果只要用分母1初始化一个
Rational
,它就可以被自动识别为整数,那就太好了。例如,我希望
x=Rational(4,1)
允许我调用
x.integer\u方法()
,甚至让
integer(4)==x
返回True。问题是,我不知道是否可以从
Rational
初始值设定项调用
Integer
初始值设定项,因为我可能会陷入无限循环


解决这个问题的最佳方法是什么(通常情况下,它不仅适用于整数和有理数,而且适用于任何父-子类型,其中父实例在初始化之前可能不会被识别为语义上等同于子类型的成员?

使用
\uuuuu new\uuuu
定义类的构造方式,包括构造其他类。避免定义ng
\uuuuu init\uuuuuuuuuuuuuuuuuuuu
,因为它不会在
\uuuuuuuuuuuuuuuuuu
返回另一种类型的对象时自动调用。由于此方案将类强耦合在一起,
Integer
可以避免调用
super()

class Rational():
    def __new__(cls, numerator, denominator=1):
        if denominator == 1:
            return Integer(numerator)
        self = object.__new__(cls)
        self.numerator = numerator
        self.denominator = denominator
        return self   # new always returns an instance

    def __repr__(self):
        return f'Rational({self.numerator}/{self.denominator})'

class Integer(Rational):
    denominator = 1  # as a Rational, Integer must expose numerator and denominator
    def __new__(cls, value):
        self = object.__new__(cls)
        self.numerator = value
        return self

    def __repr__(self):
        return f'Integer({self.numerator})'
这足以动态构造适当的子类:

>>> Rational(12, 3)
Rational(12/3)
>>> Rational(15, 1)
Integer(15)

理想情况下,这样的类应该是不可变的;否则,
Integer
作为
Rational
意味着
some\u Integer.deminator=3
是有效的,并生成一个
Rational
,初始值为1/3。

听起来像是替换构造函数的工厂方法的教科书用例。如果定义
\u新的__()
方法对于
Rational
类,当条件满足时,它可以返回一个
Integer
的实例。例如,请参阅我对问题的回答。糟糕的设计模式,不是很好SoLID@Pynchia:这不是最好的评论,因为它假设每个人都知道这是什么意思。