python函数内部函数
根据研究组的项目需求,需要用爬虫爬取一些gitlab上的项目信息,这里遇到了一个奇怪的错误。
项目背景
问题出现在scrapy的pipelines这个模块里面,当时的代码是如下的模式:
class FilesPipeline(FilesPipeline):
def get_media_requests(self,item,info):
logger = logging.getLogger()
if isinstance(item,PjItem):
for url in item['pj_code_urls']:
yield scrapy.Request(url)
elif isinstance(item,CommitItem):
url = item['commit_code']
#print 'commit_code: %s'%(url)
yield scrapy.Request(url)
elif isinstance(item,IssueItem):
pass
else:
raise DropItem('item error \n')
def item_completed(self, results, item, info):
#do something
然而,这里的最后一个方法item_completed一直不会被调用。
原因分析
眼尖的同学们可能很快就能发现,最后一个函数没有和第一个函数对齐,但是python解释器竟然没有报错。因为我之前是从Java和Android转型过来的,所以对于函数内部也能定义函数这一点十分不理解。因为在Java和C中这都是不允许的。
后来百度了很多知识也没有找到合理的解释,可能目前大多数人都只是把python认作是shell一类的脚本语言,对于其内部运行机制不像Java语言那样受关注。
后来在知乎上找到了一个链接,
[Python 里为什么函数可以返回一个函数内部定义的函数?](https://www.zhihu.com/question/25950466)
分析和总结
python中万物都是类
比较一下python和java,C++的语法可以发现,python不像java那样是完全面向对象的,它更加接近于C++,既有面向对象的部分,也有面向过程的部分,甚至可以面向函数式编程。
这里的第一个方法
def get_media_requests(self,item,info):
定义之后,Python不会把他认定是一个“函数”,Python中的函数和C语言中的函数不能同日而语。C语言的解释过程仅仅把它视为一个程序过程,汇编代码而已:
void add(int a,int b)
{
return a+b;
}
仅仅视为:(懒得去汇编了,手动写一段,正确性先不谈)
push ebp
mov ebp,esp
mov eax,[ebp-0x4]
add eax,[ebp-0x8]
pop ebp
ret
这样一段机器语言。
python的每一个方法都是视为一个类的,而在调用的时候则是把参数和其进行绑定在进行执行过程。
其他收获
闭包:所谓闭包,就是将组成函数的语句和这些语句的执行环境打包在一起时,得到的对象。
(做javascript之类的脚本语言面试的时候有可能会问到这个概念。)
引用:
`[1]: https://www.zhihu.com/question/25950466