Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 装修房屋_Python_Python Decorators - Fatal编程技术网

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,而不是需要修饰的函数,所以对它的任何调用都会立即失败,这就是为什么我将decorator
designation
指定为一个类,希望重新定义的描述符
调用
在这里会有所帮助

我不知道该怎么做。 我不断地遇到各种各样的错误,没有多少尝试和错误能让我找到解决方案

编辑

经过一段时间的工作,我成功地实现了这一点,尽管我放弃了类装饰器,但现在的问题是,它是一个实例方法,它提出了我在评论中提到的博客链接中指出的问题,即在这个链接中

我怎样才能解决这个问题

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