gpt4 book ai didi

python - __new__ 在分数模块中

转载 作者:太空狗 更新时间:2023-10-30 01:15:13 30 4
gpt4 key购买 nike

我一直在努力理解__new__ 和元编程。所以我看了一下官方的 python 源代码。

http://hg.python.org/cpython/file/2.7/Lib/fractions.py

分数的 __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 Fraction.from_float(numerator)

我以为我明白了,但现在我很困惑。

(编辑)

为了支持子类化,改成

会有什么不同吗?
return cls.from_float(numerator)

最佳答案

分数 中的代码是一个复杂的起点。最好逐步建立理解。

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) 将实例创建委托(delegate)给 Fraction.__new__() 方法。

2) Fraction.__new__() 方法使用 super() 调用 object.__new__() 来创建实际的实例.

附录

@Blckknght 想知道为什么 value 没有直接返回(创建后,它的 numerator 和 demoninator 被复制到 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 想知道“为什么不使用:return cls.from_float(numerator)”?

它叫做 Open-Closed Principle .子类应该能够覆盖 from_float() 而不会无意中破坏 __init__():

>>> class MyFraction(Fraction):
def from_float(cls, *args):
raise NotImplemented


>>> f = MyFraction(5.75)
>>> f
Fraction(23, 4)

关于python - __new__ 在分数模块中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23332052/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com