Python的函数和装饰器(包装器)中的括号

时间:2015-07-20 09:20:45

标签: python wrapper nested python-decorators

感谢您阅读我的问题。由于我还是Python的新手,我想问一下Python中的()。

def addOne(myFunc):
    def addOneInside():
        return myFunc() + 1
    return addOneInside # <-----here is the question

@addOne
def oldFunc():
    return 3

print oldFunc()

请注意,在第四行,虽然程序返回一个函数,但它不需要括号()。为什么语法错误不会出错?非常感谢你提前给出答案!

2 个答案:

答案 0 :(得分:2)

括号用于运行一个函数,但没有它们,名称仍然像函数一样引用函数。

return myFunc() + 1

这将评估myFunc函数,将其值加1,然后返回该值。需要括号才能使函数运行并返回数值。

return addOneInside

这实际上并没有运行addOneInside,它只是将函数作为变量返回。您可以将其指定给其他名称并存储以供日后使用。理论上你可以这样做:

plusOne = addOneInside
plusOne()

它实际上会调用addOneInside函数。

您的初始问题中的特定实例称为装饰器,它是您对传递给函数的参数执行代码的一种方式。您的示例不太实用,但我可以修改它以显示一个简单的用例。

让我们假设您只想将正数传递给您的函数。如果myFunc传递了一个负数,您希望它被更改为0.您可以使用这样的装饰器来管理它。

def addOne(myFunc):
    def addOneInside(num):
        if num < 0:
            num = 0
        return myFunc(num)
    return addOneInside # <-----here is the question

@addOne
def oldFunc(number):
    return number

要解释一下,@addOne是装饰器语法,只要你调用addOneInside函数,它就会在oldFunc的参数上附加oldFunc(-12) >>> 0 oldFunc(12) >>> 12 函数。所以现在这里有一些示例输出:

oldFunc

所以现在你可以添加独立于参数解析逻辑运行的public ActionResult Document(int id) { var obj = new CEATLMSEntities().LeaveDocuments.Where(c => c.Id == id).FirstOrDefault(); string[] stringParts = obj.FName.Split(new char[] { '.' }); string strType = stringParts[1]; Response.Clear(); Response.ClearContent(); Response.ClearHeaders(); Response.AddHeader("content-disposition", "attachment; filename=" + obj.FName); var asciiCode = System.Text.Encoding.ASCII.GetString(obj.Document); var datas = Convert.FromBase64String(asciiCode.Substring(asciiCode.IndexOf(',') + 1)); //Set the content type as file extension type Response.ContentType = strType; //Write the file content this.Response.BinaryWrite(datas); this.Response.End(); return new FileStreamResult(Response.OutputStream, obj.FType); } 逻辑。您还可以相对轻松地更改允许的参数。也许还有一个最大上限,或者你希望它记录或注意该值不应该是负数。您也可以将此装饰器应用于多个函数,它将对所有函数执行相同的操作。

This blogpost为我解释了很多,所以如果这些信息太简短不清楚,请尝试阅读那里详细的长篇解释。

答案 1 :(得分:0)

你在函数addOne()中的缩进是不正确的(我已修复它),但我不认为这是你的问题。

如果您使用的是Python3,那么print是一个函数,必须像这样调用:

print(oldFunc())