尝试使用 setter 为正在存储的字符串添加标签

Trying to use setter to add a label to the string being stored

我有一个@属性 和一个setter 属性。我需要 setter 将标签连接到字符串上并将其保存为新的字符串对象。这是我指的 属性 和 setter:

@property
def thesis(self):
    """Returns thesis in all capital letters"""
    return self.__thesis.upper()

@thesis.setter
def thesis(self, thesis):
    """Setter adds the label 'Thesis '"""

    self.__thesis = 'THESIS: ' + thesis

如您所见,我正在尝试向论文字符串参数添加标签 ('THESIS: '),然后将该新字符串另存为 self.__thesis。这对我不起作用。当稍后将论文打印到屏幕上时,唯一显示的是没有标签的论文。我试过弄乱名称修改以及连接字符串的不同方法,但没有任何效果。提前致谢!

有人问我如何将论文打印到屏幕上。首先论文对象被覆盖并格式化为 def str(self):

    def __str__(self):
    """Overrides overridden __str__() from our super class Student.
    Gets the full name calling supper class and gets thesis"""

    return f'{super().__str__()}\n\t{self.__thesis.upper()}'

它调用具有名字和姓氏对象的超级class,然后得到论文。每个学生对象,包括他们的 first/last 姓名和论文(如果适用)都保存到名为 students 的列表中。要实际打印上面的格式化字符串,我只是循环遍历学生中的每个学生:

    for s in students:
    print(s)
    if isinstance(s, PhDStudent): # ignore this
        print(f'\t{s.dissertation}') # ignore this

我在 class GradStudent(Student):

的初始化函数中创建了论文实例
class GradStudent(Student):
"""GradStudent is derived/inherits from the Student class.
Extends Student by adding thesis question"""

def __init__(self, thesis, first_name=''):
    # calls super class (Student's initializer) and passes first_name argument
    super().__init__(first_name)
    self.__thesis = thesis

Class定义

class Student:
    
    def __init__(self):
        self.__thesis = None
        
    @property
    def thesis(self):
        """Returns thesis in all capital letters"""
        return self.__thesis.upper()

    @thesis.setter
    def thesis(self, value):
        """Setter adds the label 'Thesis '"""

        self.__thesis = 'THESIS: ' + value
        

这按预期工作

test = Student()
test.thesis = "Test"
print (test.thesis)

结果:论文:测试

这与您的代码失败的方式相同

test = Student
test.thesis = "Test"
print (test.thesis)

结果:测试

您的 __init__ 方法未使用 属性 的 setter,因为您将其编写为直接访问基础属性 self.__thesis 而不是通过属性 的 setter。这意味着您传递给构造函数的任何论文值都不会添加前缀。

您可以通过让您的 __init__ 方法使用 self.thesis:

来解决这个问题
def __init__(self, thesis, first_name=''):
    super().__init__(first_name)
    self.thesis = thesis   # don't use double underscores here!

请注意,您可能希望 __str__ 也访问 属性 的 getter,而不是在访问 self.__thesis 时再次重复大写代码。

我注意到,Python class 设计有很多 __name_mangled 变量很少是好的标志。这听起来像是为另一种语言(如 C++ 或 Java)设计的代码,其中私有实例变量是常态。在 Python 中,大多数情况下使用没有任何前导下划线的普通变量更为传统,而当您想隐藏内部值(例如 [=34= 下的值)时,仅使用一个前导下划线]).使用 __double_underscore_prefixed_names 的名称重整旨在供混合或代理类型使用,这些类型需要避免与未知的其他类型发生名称冲突,这些类型将具有共享其名称空间的未知属性。