感谢您阅读我的问题。由于我还是Python的新手,我想问一下Python中的()。
def addOne(myFunc):
def addOneInside():
return myFunc() + 1
return addOneInside # <-----here is the question
@addOne
def oldFunc():
return 3
print oldFunc()
请注意,在第四行,虽然程序返回一个函数,但它不需要括号()。为什么语法错误不会出错?非常感谢你提前给出答案!
答案 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())