为什么我在 python 中的 f 字符串中收到超出最大递归深度的错误?

Dee*_*mar 0 python

我收到源自 f 字符串的最大递归深度错误。我是 Python 新手,不明白出了什么问题。任何帮助将不胜感激。另外,请指导我是否正确编写了构造函数?

class NearEarthObject:
    """This class represents a near earth object"""
    def __init__(self, designation, name, diameter, hazardous, approaches):
        designation = designation
        name = name
        diameter = diameter
        hazardous = hazardous
        approaches = approaches
        self.fullname = designation + "(" + name + ")"
        if len(name) == 0:
            self.fullname = designation

    @property
    def designation(self):
        return self.designation

    @designation.setter
    def designation(self, designation):
        self.designation = designation

    @property
    def name(self):
        return self.name

    @name.setter
    def name(self,name):
        self.name = name

    @property
    def diameter(self):
        return self.diameter

    @diameter.setter
    def diameter(self,diameter):
        self.diameter = diameter

    @property
    def hazardous(self):
        return self.hazardous

    @hazardous.setter
    def hazardous(self, hazardous):
        self.hazardous = hazardous

    @property
    def approaches(self):
        return self.approaches

    @approaches.setter
    def approaches(self, approaches):
        self.approaches = approaches

    def __str__(self):
        return f'NEO {self.fullname} has a diameter of {self.diameter:.3f} ' \
            f'km and {"is" if self.hazardous == True else "is not"} potentially hazardous'
Run Code Online (Sandbox Code Playgroud)

异常回溯在这里: 异常回溯

qui*_*dog 5

您的属性都是以一种方式编写的,如果您访问它们,则会导致无限递归,因为您使用的属性名称基础属性的名称相同

例如对于属性直径:

@property
def diameter(self):
    return self.diameter
Run Code Online (Sandbox Code Playgroud)

如果你运行代码

print(object.diameter)
Run Code Online (Sandbox Code Playgroud)

当它尝试确定 的值时,object.diameter它将运行该diameter(self)函数,然后尝试确定 的值,self.diameter该函数再次调用该diameter(self)函数,该函数尝试确定 的值self.diameter,等等,直到达到递归限制

当您创建属性(例如)时,您需要为实际属性diameter选择一个名称。常见的选择是使用相同的名称,并在其前面添加一个下划线。例如。所以你的直径属性将被重写为:_diameter

@property
def diameter(self):
     """provide the value of the diameter property by returning
        the underlying _diameter attribute"""
     return self._diameter
Run Code Online (Sandbox Code Playgroud)

那么您还需要更改__init__函数来设置_diameter属性。

此外,您还可以创建属性的可写版本,在这种情况下,您不需要更改您的__init__(). 您可以像这样创建可读和可写属性:

# create the readable property first

@property
def diameter(self):
     """provide the value of the diameter property by returning
        the underlying _diameter attribute"""
     return self._diameter

# then use the newly created diameter property's setter attribute
# to decorate a second function WITH THE SAME NAME which will be
# the setter

@diameter.setter  
def diameter(self, new_diameter):
    """write to the diameter property by updating the value of
       the underlying _diameter attribute"""
    _diameter = new_diameter
Run Code Online (Sandbox Code Playgroud)