试图在python中制作Circle类,现在几乎成功了,唯一剩下的问题是如何在历史列表中保留以前的半径而不是替换它[关闭]

Posted

技术标签:

【中文标题】试图在python中制作Circle类,现在几乎成功了,唯一剩下的问题是如何在历史列表中保留以前的半径而不是替换它[关闭]【英文标题】:trying to make Circle class in python, now almost successful, only problem left is how to keep previous radius in history list instead of replacing it [closed] 【发布时间】:2021-12-08 16:20:13 【问题描述】:

感谢最近评论者的帮助,我的代码现在几乎完成了。我只需要一点点帮助。我需要知道如何将所有先前的半径保留在称为历史的列表中,而不是总是将列表中的项目替换为新项目。下面是教授的指令和预期的输出,然后我将给出我写的代码:

以 3 种方式修改给出的 Circle 类:1 (a) 实现 strrepr 方法完全如下所示。 1 (b) 向实例添加属性变量历史。请注意,这不是属性, 也不是一种方法。它是一个属性,就像 radius 一样,但是,它 不是实例创建时的输入。历史 属性是一个列表,其中包含属于 圆圈,其中列表中的最后一项将与 半径的当前值。换句话说,我希望你保持一个 圆对象半径变化的历史。每一次 半径发生变化,将新值添加到列表中。初始化 init 方法中的 self.history。因为你必须做事 每当修改半径时自动,您需要使 radius 一个属性并添加一个radius“setter”属性方法。这 与直径属性相似,但有一个主要区别。你 将需要将实际半径值作为属性存储在某处 没有命名为 radius ,因为 radius 现在将是一个属性 方法。我建议为此使用一个名为 _radius 的属性变量。 请注意,一旦添加了半径 @property 和 @radius.setter ,它们 适用于任何地方,包括类的所有方法,这就是为什么你 需要一个包含实际半径值的单独属性变量。 如果你有半径 @property 方法只返回 self.radius ,你 导致递归,因为 self.radius 是什么?这是@property 半径,所以它一直在调用自己!当代码说 self.radius = new_radius ,然后使用 @radius.setter 调用 new_radius 值作为第二个参数,如果您尝试设置 self.radius 在那里,您将遇到相同的递归问题。他们俩 用于处理半径的半径方法(属性和设置器) 应该是读取/修改此实际半径值的唯一方法 属性。它应该不会出现在其他任何地方。其他方法如 init 不应引用 self._radius 。有关详细说明,请参阅本文档末尾的常见问题解答。 self._radius (或任何你 为实际半径值命名变量)和 self.history 是 两个属性变量,而不是属性。唯一使用/修改的代码 self._radius 是半径属性方法。我已经说过了吗? 是的,我做到了,因为这很重要! self.history 的最后一个值 list 应始终与 self._radius 具有相同的值,因为那是 当前的实际半径值。不要使用 self.history 代替 self._radius .

因此,根据老师的说法,当我输入这些内容时,我应该从创建 Circle 类中得到以下输出:

圆 = 圆()

圆圈

输出:圆(半径=1)

repr(圈子)

输出:'圆(半径=1)'

打印(圆圈)

输出:半径为1的圆

str(圆)

输出:'半径为 1 的圆'

圈子历史

输出应该是:[1]

circle.radius = 2

circle.diameter = 3

圆.半径

输出应该是:1.5

圈子历史

输出应该是:[1, 2, 1.5]

圆圈

输出应该是:Circle(radius=1.5)

打印(圆圈)

输出应该是:半径为 1.5 的圆

circle2 = 圆(半径=2)

circle2.history

输出应该是:[2]

circle2.radius = 2

circle2.history

输出应该是 [2, 2]

class Circle:
"""Class to create Circle objects"""

def __init__(self, radius=1):
    """Circle initializer"""
    try:
        self.radius = radius
    except ValueError:
        print("Radius cannot be negative!")
    if self.radius < 0:
        raise ValueError

def __str__(self):
    return f'Circle with a radius of self.radius'

def __repr__(self):
    return f'Circle(radius=self.radius)'

@property
def radius(self):
    return self._radius

@radius.setter
def radius(self, radius):
    doc = "The radius property."
    self._radius = radius
    self.history = []
    self.history.append(radius)

@property
def area(self):
    """Calculate and return the area of the Circle"""
    return math.pi * self.radius ** 2

@property
def diameter(self):
    """Calculate and return the diameter of the Circle"""
    return self.radius * 2

@diameter.setter
def diameter(self, diameter):
    """Set the diameter"""
    self.radius = diameter / 2

【问题讨论】:

您好,@ZA B,欢迎来到 ***。你真诚地问了一个问题,但它被关闭了。您对其进行了编辑,但编辑消失了。为什么?因为您没有正确使用 ***。您的问题应该集中在一个技术问题上。不要给我们讲故事。并且,如果您找到答案,请将其发布为答案。将问题保留为问题,不要编辑问题以将其变成答案。 *** 是一个问答平台,而不是论坛。回来问另一个问题。用你所学到的知识,让你的下一个问题变得更好! 【参考方案1】:

问题其实出在这一行:self.history = history.append(radius)

这里你将self.history设置为append方法的返回值None(你可以在这里查看:https://python-reference.readthedocs.io/en/latest/docs/list/append.html

您应该为 __init__ 方法做的事情如下:

def __init__(self, radius=1, history=list()):
    """Circle initializer"""
    try:
        self.radius = radius
        history.append(radius)
        self.history = history
    except ValueError:
        print("Radius cannot be negative!")
    if self.radius < 0:
        raise ValueError

我想你可以为“记录”部分解决剩下的问题,当你改变半径时。

【讨论】:

另外,原始代码对类的所有实例使用相同的历史列表。 history=list() 被执行一次,当 __init__ 方法被定义时,所以每次访问 self.history 时,总是同一个列表。 好的,所以我正在尝试使用 iter 方法将浮动“半径”转换为可迭代对象,但我遇到了麻烦。我知道我的代码感觉像是来自白痴,但请记住,我仍在学习 Python,而且我有学习障碍。这是我添加的代码: def __init__(self, radius=1, history): """Circle initializer""" try: self.radius = radius def __iter__(self): self.history = radius return iter(self .list) 别担心,我自己其实不是专业人士,我无法帮助 iter 部分,因为我不知道它是如何工作的,你是一个优秀的程序员,我们总是有时需要其他眼睛。 请有人帮我解决这个问题。我已经第四次修改了我的代码,我分享了它和我所有的更改,以及上面我老师的原始说明......我似乎不太明白这一点,我真的很感谢你的帮助! 该参考资料似乎严重过时。最后一次更新是从 2015 年开始,声称“此外,Python 3.X 没有赶上 - 全世界大约有七八个人在使用它。”最好改为链接到official reference。

以上是关于试图在python中制作Circle类,现在几乎成功了,唯一剩下的问题是如何在历史列表中保留以前的半径而不是替换它[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

使用python类(OOP)创建FUNCTIONAL龟对象?

从 RoundedRectangle 到 Circle 的 SwiftUI 缩放效果

在 C# 中强制转换基数组的派生成员

基于Python实现词云制作

如何使用类实现多级继承

定义一个圆类(Circle),要求用两种方法定义: 方法一: 要求属性为半径,操作为计算圆的周长和面积。 方