带参数的Python装饰器

时间:2017-04-10 10:51:12

标签: python decorator

我无法理解装饰器的概念,所以基本上如果我理解正确,装饰器用于扩展函数的行为,而不修改函数代码。基本的例子:

我有装饰器函数,它将参数作为另一个函数,然后改变作为参数给出的函数的功能:

def decorator(f):
  def wrapper(*args):
    return "Hello " + str(f(*args))
return wrapper

在这里,我有我想要装饰的功能:

@decorator
def text (txt):
'''function that returns the txt argument'''
  return txt

因此,如果我理解正确,实际发生了什么"背后"是:

d=decorator(text)
d('some argument')

我的问题是,当我们在装饰器中有三个嵌套函数时会发生什么:

def my_function(argument):
   def decorator(f):
     def wrapper(*args):
        return "Hello " +str(argument)+ str(f(*args))
    return wrapper
return decorator

@my_function("Name ")
def text(txt):
  return txt

因为功能很棒,我可以在装饰器中传递参数,我不明白这次调用后实际发生了什么:

@my_function("Name ")

谢谢,

2 个答案:

答案 0 :(得分:2)

它只是另一个间接层,基本上代码相当于:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    coordinates = (TextView)findViewById(R.id.tvCoord);
    btnStart = (Button) findViewById(R.id.btnStart);
    btnStop = (Button) findViewById(R.id.btnStop);

    if(!runtime_permissions()){
        enable_buttons();
    }
}

没有参数,你已经有了装饰器,所以

 private void enable_buttons(){
    btnStart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(getApplicationContext(),CEBGPSTracker.class);
            startService(intent);
        }
    });

    btnStop.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(getApplicationContext(),CEBGPSTracker.class);
            stopService(intent);
        }
    });
}

答案 1 :(得分:0)

my_function用于在此处创建闭包。 argument位于my_function的本地。但由于关闭,当您返回decorator时,decorator函数始终引用它。因此,当您将decorator应用于text时,decorator会添加额外的功能,这是预期的。它还可以在其额外功能中嵌入argument,因为它可以访问定义它的环境。