英文:
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("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.
答案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("Invalid password")
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("Invalid password")
return f(*args, **kwargs)
return wrapper
return decorator
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论