覆盖使用@property设置的属性

时间:2019-09-05 12:36:32

标签: python

我想知道在这种情况下如何更新使用@property装饰器设置的属性。 (下面的代码将告诉您更多的信息……)

当我尝试不使用设置器更新电子邮件时,出现AttributeError:无法设置属性。当我使用二传手时,什么都不会改变。新电子邮件既不使用姓氏也不使用姓氏。

有人可以帮忙吗?

class Employee:
    def __init__(self, first, last):
        self.first = first
        self.last = last

    @property
    def email(self):
        return f"{self.first}.{self.last}@email.com".lower()

    # @email.setter
    # def email(self, new_email):
    #     return new_email

2 个答案:

答案 0 :(得分:2)

我认为这里最直接的途径是取消该属性,而将createRequest<R>(url, {as: "json"})设为默认为R的可选参数:

email

现在,您可以使用通常的点符号来修改现有实例的电子邮件地址:

first.last

如果您确实打算保留该属性,则setter需要更新实例属性:

class Employee:
    def __init__(self, first, last, email=None):
        self.first = first
        self.last = last
        self.email = email if email else f"{first}.{last}@email.com".lower()

如果您需要进行某种验证,则可以选择此模式-例如,确认新电子邮件具有>>> e = Employee('John', 'Doe') >>> e.email 'john.doe@email.com' >>> >>> e.email = 'a@b.com' >>> e.email 'a@b.com' 符号:

class Employee:
    def __init__(self, first, last):
        self.first = first
        self.last = last
        self._email = f"{first}.{last}@email.com".lower()

    @property
    def email(self):
        return self._email

    @email.setter
    def email(self, addr):
        self._email = addr

但是否则第一种选择会更简单。

答案 1 :(得分:0)

正如我在评论中所述,您需要确定新电子邮件是否位于first.last@email.com中,然后只需设置firstlast属性即可。

尽管如果您根据名称创建电子邮件,我不会将其用作属性,但是您应该更改名称本身。

class Employee:
    def __init__(self, first, last):
        self.first = first
        self.last = last

    def email(self):
        return f"{self.first}.{self.last}@email.com".lower()

    def __repr__(self):
      return f"<Employee | {self.first} {self.last}>"

john = Employee('John', 'Smith')
print(john)
#<Employee | John Smith>
john.first = "Joe"
print(john)
#<Employee | Joe Smith>

否则,如果您想使用电子邮件的setter,那么我建议您使用它来设置第一个和最后一个属性,但是您不需要返回值,因为您只需要设置已经知道的电子邮件即可。我将使用re库来检查电子邮件的格式是否正确。这是一个非常粗糙的示例:

@email.setter
def email(self, new_email):
    try:
        self.first, self.last = re.search('(?P<first>\w+).(?P<last>\w+)@\S+', email).group('first', 'last'))
    except AttributeError:
        raise ValueError("Email must be in "first.last@email.com")