Python 装修房屋
我试图装饰一个实例方法,它用另一个方法打印全名,这个方法只是添加了一个名称,我已经设法弄明白了这一点Python 装修房屋,python,python-decorators,Python,Python Decorators,我试图装饰一个实例方法,它用另一个方法打印全名,这个方法只是添加了一个名称,我已经设法弄明白了这一点 class DecoratorTest: def __init__(self): self._first_name = ['CHARLES', 'WILIAM', 'ENID'] self._last_name = ['DICKENS', 'SHAKESPEARE', 'BLYTON'] self._full_name = None
class DecoratorTest:
def __init__(self):
self._first_name = ['CHARLES', 'WILIAM', 'ENID']
self._last_name = ['DICKENS', 'SHAKESPEARE', 'BLYTON']
self._full_name = None
class designation(object):
def __init__(self, decorated):
self._decorated = decorated
def __call__(self, *args, **kwargs):
self._full_name = "MR" + self._decorated()
return self._full_name
@designation()
def full_name(self):
if not self._full_name:
self._full_name = random.choices(self._first_name) + random.choices(self._last_name)
return self._full_name
a = DecoratorTest()
print(a.full_name())
通过阅读,我发现decorator@designation不能是一个实例方法,因为第一个参数是self,而不是需要修饰的函数,所以对它的任何调用都会立即失败,这就是为什么我将decoratordesignation
指定为一个类,希望重新定义的描述符调用
在这里会有所帮助
我不知道该怎么做。
我不断地遇到各种各样的错误,没有多少尝试和错误能让我找到解决方案
编辑
经过一段时间的工作,我成功地实现了这一点,尽管我放弃了类装饰器,但现在的问题是,它是一个实例方法,它提出了我在评论中提到的博客链接中指出的问题,即在这个链接中
我怎样才能解决这个问题
import random
class DecoratorTest:
def __init__(self):
self._first_name = ['CHARLES', 'WILIAM', 'ENID']
self._last_name = ['DICKENS', 'SHAKESPEARE', 'BLYTON']
self._full_name = None
def designation(func):
def wrapper(self):
full_name = "MR" + func(self)
return full_name
return wrapper
@designation
def full_name(self):
if not self._full_name:
self._full_name = str(random.choices(self._first_name)) + str(random.choices(self._last_name))
return self._full_name
a = DecoratorTest()
print(a.full_name())
我玩了一会儿,发现了这个解决方案:
类装饰测试:
定义初始化(自):
self._first_name=['CHARLES','WILIAM','ENID']
self._last_name=['DICKENS','SHAKESPEARE','BLYTON']
self.\u full\u name=无
类别名称(对象):
定义初始值(自我、装饰、*args、**kwargs):
打印(str(*args))
打印(str(**kwargs))
自我装饰的
定义调用(self,*args,**kwargs):
全名=“MR”+自我装饰(自我)
返回全名
@名称
def全名(自我):
如果不是DecoratorTest()。\u全名\u:
全名=“”.join([random.choices(DecoratorTest().\u first\u name)[0],random.choices(DecoratorTest().\u last\u name)[0]])
返回全名
主要问题是,您使用内部装饰器类装饰外部方法,这导致了问题,外部方法中的self
可能指向内部方法。我使用类名本身来指向正确的值
这只是一个快速的,它可能不是100%准确
您好,Thomas我玩了一会儿,发现了这个解决方案:
类装饰测试:
定义初始化(自):
self._first_name=['CHARLES','WILIAM','ENID']
self._last_name=['DICKENS','SHAKESPEARE','BLYTON']
self.\u full\u name=无
类别名称(对象):
定义初始值(自我、装饰、*args、**kwargs):
打印(str(*args))
打印(str(**kwargs))
自我装饰的
定义调用(self,*args,**kwargs):
全名=“MR”+自我装饰(自我)
返回全名
@名称
def全名(自我):
如果不是DecoratorTest()。\u全名\u:
全名=“”.join([random.choices(DecoratorTest().\u first\u name)[0],random.choices(DecoratorTest().\u last\u name)[0]])
返回全名
主要问题是,您使用内部装饰器类装饰外部方法,这导致了问题,外部方法中的self
可能指向内部方法。我使用类名本身来指向正确的值
这只是一个快速的,它可能不是100%准确
你好,托马斯(下)
首先让我们提醒自己装饰师是做什么的
它们是可调用函数/函数,将函数作为输入并返回新函数(修饰)
这意味着我们可以装饰这样的功能
def return_hello():
return "hello "
def multiply_by_5(func):
def new_func(*args,**kwargs):
return func(*args, **kwargs) * 5
multiply_by_5(return_hello)()
或者使用@语法
@multiply_by_5
def return_hello():
return "hello "
return_hello()
因此,在您的示例中,您已经用
@designation()
这是通过_call__方法模拟可调用的(请参阅)。这意味着_调用_方法被传递给函数(即_调用_方法实际上是这里的装饰器)
因此,您可以像这样修复代码:
...
class designation():
def __call__(self, func):
def new_func(*n_args, **n_kwargs):
return "MR" + func(*n_args,**n_kwargs)
return new_func
@designation()
def full_name(self):
...
编辑2:你也可以像这样添加属性装饰器,它会工作的
@property
@designation()
def full_name(self):
...
编辑3:您也可以通过一个简单的基于函数的装饰器来实现所有这些。所以,除非你真的需要你的装饰者成为一个类,否则我会推荐这个
def designation(func):
def new_func(*args, **kwargs):
name = func(*args, **kwargs)
return "MR" + name
return new_func
TLDR(转至底部)
首先让我们提醒自己装饰师是做什么的
它们是可调用函数/函数,将函数作为输入并返回新函数(修饰)
这意味着我们可以装饰这样的功能
def return_hello():
return "hello "
def multiply_by_5(func):
def new_func(*args,**kwargs):
return func(*args, **kwargs) * 5
multiply_by_5(return_hello)()
或者使用@语法
@multiply_by_5
def return_hello():
return "hello "
return_hello()
因此,在您的示例中,您已经用
@designation()
这是通过_call__方法模拟可调用的(请参阅)。这意味着_调用_方法被传递给函数(即_调用_方法实际上是这里的装饰器)
因此,您可以像这样修复代码:
...
class designation():
def __call__(self, func):
def new_func(*n_args, **n_kwargs):
return "MR" + func(*n_args,**n_kwargs)
return new_func
@designation()
def full_name(self):
...
编辑2:你也可以像这样添加属性装饰器,它会工作的
@property
@designation()
def full_name(self):
...
编辑3:您也可以通过一个简单的基于函数的装饰器来实现所有这些。所以,除非你真的需要你的装饰者成为一个类,否则我会推荐这个
def designation(func):
def new_func(*args, **kwargs):
name = func(*args, **kwargs)
return "MR" + name
return new_func
full_name
未作为参数传递给指定;它作为一个参数传递给designation.\uuuu调用\uuuu
,一旦创建了实例。我不明白你想用decorator解决什么问题。但是也许你会发现答案很有用,尽管这是一个不同的问题。@KarlKnechtel,我试图通过自己写一个例子来理解如何修饰实例方法。我用它作为参考,但我很难实现它。有趣的问题。一个快速搜索给了我这个链接:@ThomasKlinger,你能帮我解决这个问题吗?该链接演示了如何使用类来修饰方法,我想用一个内部类来修饰一个实例方法,如我共享的链接的最后一段所建议的。full_name
不是作为参数传递给指定。uuu init_u
;它作为参数传递给de