I have a method that set the name
variable but there isn't global name
at the first line of it, It uses local name
variable so It never changes the global name
variable. Is there any way that by decorating set_name
force it to use global name
?
name = "John"
def set_name():
name = "Sara"
def print_name():
global name
print(name)
def decorator(func):
def wrapper(*args, **kwargs):
## Problem:
# Force set_name to use global 'name'
func(*args, **kwargs)
return wrapper
print_name()
#Output: John
decorator(set_name)()
print_name()
# Prints John, but I want to prints Sara
No, unless the decorator takes the function's code (bytecode from the function's code object, or source code using inspect
), changes it, creates a new code object from the changed code and replaces the function's code with that. Which is, of course, highly unreliable, hacky, implementation-specific and deep black magic. Just add global name
(or eliminate the global variable altogether).
The short answer is: no.
A bit extended answer: no, not in a portable way. Technically, you could play around with the CPython bytecode, but
name = "John" #global name
and name inside set_name():
name = "Sara" #local name
To use global name inside function set_name()
do like:
def set_name():
global name
name = "Sara"
Define a class that wraps name
:
class Person(object):
def __init__(self):
self.name = "John"
def set_name(self):
self.name = "Sara"
def print_name(self):
print(name)
p = Person()
p.print_name() # Prints John
p.set_name() # Changes name to Sara
p.print_name() # Prints Sara
A class which hard-codes its attribute values like this is, of course, a little silly, but this demonstrates the purpose of a class: to encapsulate data ( name
) and the functions ( set_name
, print_name
) that operate on it.
Not sure, why you are trying to decorate the setter.
You can do something like this, but I would not recommend it as a usual style of coding:
name = "John"
def print_name():
print name
def decorator(func, tmp_name):
def wrapper(*args, **kwargs):
global name
old_name = name
name = tmp_name
func(*args, **kwargs)
name = old_name
return wrapper
print_name()
decorator(print_name, 'Sarah')()
print_name()
Output:
John
Sarah
John
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.