我一直在努力理解__new__
和元编程。所以我看了一下官方的python源代码。
http://hg.python.org/cpython/file/2.7/Lib/fractions.py
他们对于Fractions的__new__
函数如下所示:
class Fraction(Rational):
def __new__(cls, numerator=0, denominator=None):
"""Constructs a Fraction. ... """
self = super(Fraction, cls).__new__(cls)
...
if isinstance(numerator, float):
# Exact conversion from float
value = Fraction.from_float(numerator)
self._numerator = value._numerator
self._denominator = value._denominator
return self
@classmethod
def from_float(cls, f):
"""Converts a finite float to a rational number, exactly. ..."""
# ...
return cls(*f.as_integer_ratio())
为什么他们return self
,而不是
return Fraction.from_float(numerator)
我以为我明白了,但现在我很困惑。
(编辑)
为了支持子类化,改变为
会有什么不同return cls.from_float(numerator)
答案 0 :(得分:4)
Fractions 中的代码是一个复杂的起点。最好逐步建立一个理解。
1)object .__ new__是创建新式类实例的根工具:
o = object()
2)定义__new__的类通常调用object .__ new__来完成它的工作:
class A(object):
def __new__(cls):
return object.__new__(cls)
a = A()
3)一种类方法通常依赖于班级的__new__来完成它的工作:
class A(object):
def __new__(cls):
return object.__new__(cls)
@classmethod
def from_something(cls):
return cls.__new__()
有了这样的理解,你可以看到分数模块正在做什么:
1) from_float()调用cls(numerator, denominator)
将实例创建委托给Fraction .__ new __()方法。
2) Fraction .__ new __()方法使用 super()来调用 object .__ new __()来进行实际的实例创建
<强>附加物强>
@Blckknght想知道为什么value
没有被直接返回(在创建之后,它的分子和幻象者在self
被扔掉之前复制到value
答案是Fraction.from_float
创建 Fraction 而不是 cls 的实例。换句话说,代码提供了对子类化的支持:
>>> from fractions import Fraction
>>> class MyFraction(Fraction):
pass
>>> f = MyFraction(2, 3)
>>> f
Fraction(2, 3)
>>> f.__class__ # this MUST be MyFraction, not a Fraction
<class '__main__.MyFraction'>
修改强>
@richard想知道&#34;为什么不使用:return cls.from_float(numerator)&#34;?
它被称为Open-Closed Principle。子类格式应该能够覆盖 from_float()而不会无意中破坏 __ init __():
>>> class MyFraction(Fraction):
def from_float(cls, *args):
raise NotImplemented
>>> f = MyFraction(5.75)
>>> f
Fraction(23, 4)