属性没有设置者

问题描述 投票:0回答:1

我的代码有错误:

Traceback (most recent call last):
  File "c:\Users\Designer5.PUCCINI.000\Documents\pws256\pws256\src\__init__.py", line 116, in <module>
    pw.hsh_func = ""
    ^^^^^^^^^^^
AttributeError: property 'hsh_func' of '_Password' object has no setter

这是我的代码:

class _Password:
    def __init__(self, hashed, hsh_func, hsh_enter, hsh_after, salt):
        self.hashed = hashed
        self._hsh_enter = hsh_enter
        self._hsh_func = hsh_func
        self._hsh_after = hsh_after
        self.__salt = salt

    @property
    def hsh_func(self):
        return self._hsh_func
    
    @hsh_func.setter
    def set_hsh_func(self, obj):
        if not isinstance(obj, function):
            raise TypeError(
                f"obj must be a function, not {obj.__class__.__name__}"
            )
        self._hsh_func = obj

    @property
    def salt(self):
        return self.__salt
    
    @property
    def hsh_after(self):
        return self._hsh_after
    
    @hsh_after.setter
    def set_hsh_after(self, obj):
        if not isinstance(obj, str):
            raise TypeError(
                f"obj must be of type 'str', not {obj.__class__.__name__}"
            )
    

    def validate(self, other: str):
        "Validate a password using the hsh_func entered on creation"
        print(hl.sha256(other.encode()).hexdigest(), self.salt)
        encoded = self.hsh_func(((self.salt + other) if self.hsh_enter == str else (self.salt + other).encode()))
        if self.hsh_after:
            encoded = eval("encoded" + self.hsh_after, dict({"encoded": encoded})) # Add hsh_after e.g. hashlib.sha256(b"hello").hexdigest()

        return encoded == self.hashed
    

pw = _Password(hashlib.sha256("hello".encode()).hexdigest(), hashlib.sha256, ".hexdigest()")
pw.hsh_func = hashlib.sha512
python
1个回答
0
投票

Python 装饰器语法:

@decorator
def function():
    ...

语法糖,用于:

def function():
    ...


function = decorator(function)

同样,在类内部使用装饰器时:

class Foo:

    @property
    def bar(self):
        ...

    @bar.setter
    def set_bar(self, value):
        ...

变成:

class Foo:

    def bar(self):
        ...

    bar = property(bar)

    def set_bar(self, value):
        ...

    set_bar = bar.setter(set_bar)
    # ^^^^^ - problem

您通常想要的属性是获取和设置相同的属性,在上面的示例中为

bar
。要完成这项工作,您需要:

    bar = bar.setter(...)

使用装饰器语法意味着对装饰方法使用相同的名称

    @bar.setter
    def bar(self, value):
        ...
© www.soinside.com 2019 - 2024. All rights reserved.