密码装饰器

huangapple go评论82阅读模式
英文:

Password decorator

问题

I have to solve the following problem which doesn't allow me to change the add() function, i.e. it needs to work for all 'untouched' functions that are decorated by the @password("my_pswd"), meaning I cannot change the add() function. I am not familiar with passing such an argument to a function and transfer it to the decorator. As for how I tried solving this issue, the decorator (which is the only thing I may change) is included in the original question.

Decorator:

Write a parameterized decorator named "password" that takes a password as a parameter.
The decorated function should take this password as a parameter and return its result. If the password is not provided, it should raise a ValueError exception. The decorator should work with any function regardless of its named and positional parameters.

Example:

@password("secret")
def add(a, b):   #constant function, DO NOT MODIFY
    return a + b

add("h", 1, 2)   # ValueError
add(1, 2)        # ValueError
add("secret", 1, 2)    # 3

def password(pswd):
    # code here

I've tried using a named decorator like this:

def password(pswd):
    def decorator(f):
        def wrapper(*args, **kwargs):
            if not f(*args) is pswd:
                raise ValueError("Invalid password")
            return f(*args, **kwargs)
        return wrapper
    return decorator

But, I get:

line 28, in <module>
    add("h", 1, 2)
  File "<>", line 16, in wrapper 
    if not f(*args) is pswd:
TypeError: add() takes 2 positional arguments but 3 were given

Any idea how to solve this? To be clear, I can't modify the add function, meaning I cannot give it a third positional argument.

英文:

I have to solve the follwing problem which doesn't allow me to change the add() function, i.e. it needs to work for all 'untouched' functions that are decorated by the @password(&quot;my_pswd&quot;), meaning I cannot change the add() function. I am not familiar with passing such an argument to a function and transfer it to the decorator. As for how i tried solving this issue, the decorator (which is the only thing I may change) is included in the original question.

Decorator:

> Write a parameterized decorator named "password" that takes a password as a parameter.
> The decorated function should take this password as a parameter and return its result. If the password is not provided, it should raise a ValueError exception. The decorator should work with any function regardless of its named and positional parameters.

Example:

@password(&quot;secret&quot;)
def add(a, b):   #constant function, DO NOT MODIFY
	return a+b
	
add(&quot;h&quot;, 1, 2)   #ValueError
add(1, 2)            #ValueError
add(&quot;secret&quot;, 1, 2)    #3

def password(pswd):
    #code here

I've tried using a named decorator like this :

def password(pswd):
	def decorator(f):
		def wrapper(*args, **kwargs):
			if not f(*args) is pswd:
				raise ValueError(&quot;Invalid password&quot;)
			return f(*args, **kwargs)
		return wrapper
	return decorator

But, I get

line 28, in &lt;module&gt;
    add(&quot;h&quot;, 1, 2)
  File &quot;//&quot;, line 16, in wrapper 
    if not f(*args) is pswd:
TypeError: add() takes 2 positional arguments but 3 were given

Any idea how to solve this? To be clear, I can't modify the add function, meaning I cannot give it a third positional argument.

答案1

得分: 0

以下是您要翻译的代码部分:

# 包装函数应该只检查第一个参数是否为密码。当包装函数调用原始函数时,必须省略密码参数。因此,函数签名应该是
def wrapper(password_given, *args, **kwargs):
# 这允许它仅传递`*args`到原始函数,省略第一个参数。
# 然后,它应该使用 `if pswd != pass:` 来检查密码 - 您不应该使用 `is` 来比较字符串。
def password(pswd):
    def decorator(f):
        def wrapper(password_given, *args, **kwargs):
            if password_given != pswd:
                raise ValueError("Invalid password")
            return f(*args, **kwargs)
        return wrapper
    return decorator
英文:

The wrapper function should just check if the first argument is the password. And when the wrapper calls the original function it has to leave out the password argument. So the function signature should be

def wrapper(password_given, *args, **kwargs):

This allows it to pass only *args to the original function, which leaves out the first argument.

Then it should use if pswd != pass: to check the password -- you shouldn't use is to compare strings.

def password(pswd):
    def decorator(f):
        def wrapper(password_given, *args, **kwargs):
            if password_given != pswd:
                raise ValueError(&quot;Invalid password&quot;)
            return f(*args, **kwargs)
        return wrapper
    return decorator

答案2

得分: 0

我已经问过了,这是我得出的结论:

我们遇到的问题是因为我们在装饰器的包装函数内调用了add()函数,并将所有参数都传递给它,包括密码。然而,add()函数不希望将密码作为参数,这导致了"TypeError: add() takes 2 positional arguments but 3 were given"错误。为了解决这个问题而不修改add()函数,我们可以修改装饰器的包装函数,接受密码作为单独的参数。

def password(pswd):
    def decorator(f):
        def wrapper(pswd_arg, *args, **kwargs):
            if pswd_arg != pswd:
                raise ValueError("Invalid password")
            return f(*args, **kwargs)
        return wrapper
    return decorator
英文:

I've asked around and this is the conclusion I get :

The issue we're encountering is due to the fact that we're calling the add() function inside the decorator's wrapper with all the arguments passed to it, including the password. However, the add() function does not expect the password as an argument, which results in the "TypeError: add() takes 2 positional arguments but 3 were given" error. To solve this problem while not modifying the add() function, we can modify the decorator's wrapper to accept the password as a separate argument.

def password(pswd):
    def decorator(f):
        def wrapper(pswd_arg, *args, **kwargs):
            if pswd_arg != pswd:
                raise ValueError(&quot;Invalid password&quot;)
            return f(*args, **kwargs)
        return wrapper
    return decorator

huangapple
  • 本文由 发表于 2023年6月13日 08:29:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76461029.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定