免费刷金币,请点击这里
TE社区 > 后端开发
客服QQ:1206116161

讲解Python中for循环下的索引变量的作用域

u010775860 于 2019-01-30 15:09:07 创建话题
(5)
(0)
举报

我们从一个测试开始。下面这个函数的功能是什么?
 

def foo(lst):
  a = 0
  for i in lst:
    a += i
  b = 1
  for t in lst:
    b *= i
  return a, b

如果你觉得它的功能是“计算lst中所有元素的和与积”,不要沮丧。通常很难发现这里的错误。如果在大堆真实的代码中发现了这个错误就非常厉害了。——当你不知道这是一个测试时,很难发现这个错误。

这里的错误是在第二个循环体中使用了i而不是t。等下,这到底是怎么工作的?i在第一个循环外应该是不可见的? [1]哦,不。事实上,Python正式声明过,为for循环目标(loop target)定义的名称(更严格的正式名称为“索引变量”)能泄露到外围函数范围。因此下面的代码:
 

for i in [1, 2, 3]:
  pass
print(i)

这段代码是有效的,可以打印出3。在本文中,我想探讨一下为什么会这样,为什么它不太可能改变,以及将它作为一颗追踪子弹来挖掘CPython编辑器中一些有趣的部分。

顺便说一句,如果你不相信这种行为可能会导致真正的问题,考虑这个代码片断:
 

def foo():
  lst = []
  for i in range(4):
    lst.append(lambda: i)
  print([f() for f in lst])

如果你期待上面的代码能打印出[0,1,2,3],你的期望会落空的,它会打印出[3,3,3,3];因为在foo的作用域内只有一个i,这个i就是所有的lambda所捕获的。
官方说明

Python参考文档中的for循环部分明确地记录了这种行为:

    for循环将变量赋值到目标列表中。……当循环结束时,赋值列表中的变量不会被删除,但如果序列是空的,它们将不会被赋值给所有的循环。

注意最后一句,让我们试试:
 

for i in []:
  pass
print(i)

的确,上面的代码抛出NameError异常。稍后,我们将看到这是Python虚拟机执行字节码方式的必然结果。
为什么会是这样

其实我问过Guido van Rossum有关这个执行行为的原因,他很慷慨地告诉了我其中的一些历史背景(感谢Guido!)。这样执行代码的动机是保持Python获得变量和作用域的简单性,而不诉诸于hacks(例如在循环完成后,删除定义在该循环中的所有变量——想想它可能引发的异常)或更复杂的作用域规则。

Python的作用域规则非常简单、优雅:模块、类以及函数的代码块可引入作用域。在函数体内,变量从它们定义到代码块结束(包括嵌套的代码块如嵌套函数)都是可见的。当然,对于局部变量、全局变量(以及其他nonlocal变量)其规则略有不同。不过,这和我们的讨论没有太多关系。

这里最重要的一点是:最内层的可能作用域是一个函数体。不是一个for循环体。不是一个with代码块。Python与其他编程语言不同(例如C及其后代语言),在函数水平下没有嵌套词法作用域。

因此,如果你只是基于Python实现,你的代码可能会以这样的执行行为结束。下面是另一段令人启发的代码片段:
 

for i in range(4):
  d = i * 2
print(d)

变量d 在for循环结束后是可见及可访问的,你对这样的发现感到惊奇吗?不,这正是Python的工作方式。那么,为什么索引变量的作用域被区别对待呢?

顺便说一句,列表推导式(list comprehension)中的索引变量也泄露到其封闭作用域,或者更准确的说,在Python 3之前可以泄露。

Python 3包含许多重大更改,其中也修复了列表推导式中的变量泄露问题。毫无疑问,这样破坏了向后兼容中性。这就是我认为当前的执行行为不会被改变的原因。

此外,许多人仍然发现这是Python中的一个有用的功能。考虑一下下面的代码:
 

for i, item in enumerate(somegenerator()):
  dostuffwith(i, item)
print('The loop executed {0} times!'.format(i+1))

如果不知道somegenerator返回项的数目,可以使用这种简洁的方式。否则,你就必须有一个独立的计数器。

这里有一个其他的例子:
 

for i in somegenerator():
  if isinteresing(i):
   break
dostuffwith(i)

这种模式可以有效的在循环中查找某一项并在随后使用该项。[2]

多年来,许多用户都想保留这种特性。但即使对于开发者认定的有害特性,也很难引入重大更改了。当许多人认为该特性很有用,而且在真实世界的代码中大量使用时,就更不会除去这项特性了。
Under the hood

现在是最有趣的部分。让我们来看看Python编译器和VM是如何协同工作,让这种代码执行行为成为可能的。在这种特殊的情况下,我认为呈现这些的最清晰方式是从字节码开始逆向分析。我希望通过这个例子来介绍如何挖掘Python内部[3]的信息(这是如此充满乐趣!)。

让我们来看本文开篇提出的函数的一部分:
 

def foo(lst):
  a = 0
  for i in lst:
    a += i
  return a

产生的字节码是:
 

 0 LOAD_CONST        1 (0)
 3 STORE_FAST        1 (a)
 
 6 SETUP_LOOP       24 (to 33)
 9 LOAD_FAST        0 (lst)
12 GET_ITER
13 FOR_ITER        16 (to 32)
16 STORE_FAST        2 (i)
 
19 LOAD_FAST        1 (a)
22 LOAD_FAST        2 (i)
25 INPLACE_ADD
26 STORE_FAST        1 (a)
29 JUMP_ABSOLUTE      13
32 POP_BLOCK
 
33 LOAD_FAST        1 (a)
36 RETURN_VALUE

作为提示,LOAD_FAST和STORE_FAST是字节码(opcode),Python用它来访问只在函数中使用的变量。由于Python编译器知道(编译时)在每个函数中有多少个这样的静态变量,它们可以通过静态数组偏移量而不是一个哈希表进行访问,这使得访问速度更快(因而是_FAST后缀)。我有些离题了。这里真正重要的是变量a和i被平等对待。它们都通过LOAD_FAST获取,并通过STORE_FAST修改。绝对没有任何理由认为它们的可见性是不同的。[4]

那么,这种执行现象是怎么发生的?为什么编译器认为变量i只是foo中的一个局部变量。这个逻辑在符号表中的代码中,当编译器执行到AST开始创建一个控制流图,随后会产生字节码。这个过程的更多细节在我有关符号表的文章中的介绍——所以我只在这里提及其中的重点。

符号表代码并不认为for语句很特别。在symtable_visit_stmt中有如下代码:
 

case For_kind:
  VISIT(st, expr, s->v.For.target);
  VISIT(st, expr, s->v.For.iter);
  VISIT_SEQ(st, stmt, s->v.For.body);
  if (s->v.For.orelse)
    VISIT_SEQ(st, stmt, s->v.For.orelse);
  break;

索引变量如任何其他表达式一样被访问。由于该代码访问了AST,这值得去看看for语句结点内部是怎样的:
 

For(target=Name(id='i', ctx=Store()),
  iter=Name(id='lst', ctx=Load()),
  body=[AugAssign(target=Name(id='a', ctx=Store()),
          op=Add(),
          value=Name(id='i', ctx=Load()))],
  orelse=[])

所以i在一个名为Name的节点中。这些是由符号表代码通过symtable_visit_expr中以下语句来处理的:
 

case Name_kind:
  if (!symtable_add_def(st, e->v.Name.id,
             e->v.Name.ctx == Load ? USE : DEF_LOCAL))
    VISIT_QUIT(st, 0);
  /* ... */

由于变量i被清楚地标记为DEF_LOCAL(因为* _FAST字节码是可访问的,但是这也很容易观察到,如果符号表是不能用的则使用symtable模块),上述明显的代码调用symtable_add_def与DEF_LOCAL 作为第三个参数。现在来浏览一下上面的AST,并注意到Name结点中i的ctx=Store部分。因此,它是在For结点的target部分存储着i的信息的AST。让我们看看这是如何实现的。

编译器中的AST构建部分越过了解析树(这是源代码中相当底层的表示——一些背景资料可以在这里获得),同时在其他事项中,在某些结点设置expr_context属性,其中最显著的是Name结点。想想看,这样一来,在下面的语句:
 

foo = bar + 1

for和bar这两个变量都将在Name结点中结束。但是bar只是被加载到这段代码中,而for实际上被存储到这段代码中。expr_context属性通过符号表代码被用来区分当前和未来使用[5] 。

回到我们for循环的索引变量。这些内容将在函数ast_for_for_stmt——for语句创建AST——中处理。下面是该函数的相关部分:
 

static stmt_ty
ast_for_for_stmt(struct compiling *c, const node *n)
{
  asdl_seq *_target, *seq = NULL, *suite_seq;
  expr_ty expression;
  expr_ty target, first;
 
  /* ... */
 
  node_target = CHILD(n, 1);
  _target = ast_for_exprlist(c, node_target, Store);
  if (!_target)
    return NULL;
  /* Check the # of children rather than the length of _target, since
    for x, in ... has 1 element in _target, but still requires a Tuple. */
  first = (expr_ty)asdl_seq_GET(_target, 0);
  if (NCH(node_target) == 1)
    target = first;
  else
    target = Tuple(_target, Store, first->lineno, first->col_offset, c->c_arena);
 
  /* ... */
 
  return For(target, expression, suite_seq, seq, LINENO(n), n->n_col_offset,
        c->c_arena);
}

在调用函数ast_for_exprlist时创建了Store上下文,该函数为索引变量创建了一个结点(注意,for循环的索引变量还可能是一序列变量的元组,而不仅仅是一个变量)。

在介绍为什么for循环变量和循环中的其他变量一视同仁的过程中,这个函数是最后总要的一部分。在AST中进行标记之后,在符号表和虚拟机中用于处理循环变量的代码与处理其他变量的代码是相同的。
结束语

本文讨论了Python中可能被认为是“疑难杂症”的某些特定行为。我希望这篇文章确实解释了Python的变量和作用域的代码执行行为,说明了为什么这些行为是有用的而且永远不太可能改变,以及Python编译器的内部如何使其正常工作。感谢您的阅读!

[1] 在这里,我很想开个Microsoft Visual C ++ 6的玩笑,但事实让人有些不安,因为在2015年这个博客的大部分读者不会懂这个笑话(这反映了我的年龄,而不是我的读者的能力)。

[2] 你可能会说,在执行到break之前时,dowithstuff(i)可以进入if中。但是,这并不总是很方便。此外,根据Guido的解释,这里对我们关注的问题做了一个很好的分离——循环被用于并只用于搜索。在搜索结束后,循环中的变量会发生什么已经不是循环关注的事情。我觉得这是非常好的一点。

[3]: 通常我的文章中的代码是基于Python 3。具体而言,我期待Python库中将要完成的下一个版本(3.5)的default分支。但是对于这个特定的主题,在3.x系列中的任何版本的源代码都应该是可以工作的。

[4] 函数分解中另一件很明显的事是,如果循环不执行,为什么i仍然是不可见的,GET_ITER和FOR_ITER这对字节码将我们的循环当做一个迭代器,然后调用其__next__方法。如果这个调用最后以抛出StopIteration异常结束,虚拟机捕捉到这个异常然后结束循环。只有实际值被返回,虚拟机才会继续对i执行STORE_FAST,因此让这个值存在,让后续代码可以引用。

[5] 这是一个奇怪的设计,我怀疑这个设计的实质是为了使用相对干净的递归访问AST中的代码,如符号表代码和CFG生成器。

扫码关注TE官方微博 扫码关注TE官方微博
js jquery验证银行卡号信息正则学习 JavaScript定时器详解及实例 javascript实现状态栏文字首尾相接循环滚动的方法 浅谈javascript中onbeforeunload与onunload事件 web前端开发中常见的多列布局解决方案整理(一定要看) jquery插件冲突(jquery.noconflict)解决方法分享 asp.net(C#)防sql注入组件的实现代码 JS实现图片平面旋转的方法 jQuery判断浏览器并动态调整select宽度的方法 js滚动条回到顶部的代码 SQL字段拆分优化 实现按关健字模糊查询,并按匹配度排序的SQL语句 详解Swift的switch...case语句中break关键字的用法 asp.net 多字段模糊查询代码 Bootstrap的popover(弹出框)在append后弹不出(失效) Pycharm学习教程(7)虚拟机VM的配置教程 jQuery方法简洁实现隔行换色及toggleClass的使用 Python入门篇之面向对象 nodejs中实现路由功能 python访问类中docstring注释的实现方法 Angularjs 与 bower安装和使用详解 Tomcat 服务器 在45秒内未启动成功的解决方法 ReactNative 之FlatList使用及踩坑封装总结 json2.js 入门教程之使用方法与实例分析 React Native使用百度Echarts显示图表的示例代码 基于JavaScript实现五子棋游戏 Python读取Excel的方法实例分析 js倒计时抢购实例 JavaScript函数的调用以及参数传递 JS深度拷贝Object Array实例分析 asp 空值测试判断函数 asp.net下使用AjaxPro实现二级联动代码 Linux系统中使用dd命令检测硬盘性能的方法 ExtJS判断IE浏览器类型的方法 原生javascript实现隔行换色 关于HTML5的安全问题开发人员需要牢记的 PHP实现Javascript中的escape及unescape函数代码分享 Python备份目录及目录下的全部内容的实现方法 Angular项目从新建、打包到nginx部署全过程记录 JSON 数据格式介绍 Jquery post传递数组方法实现思路及代码 在react-router4中进行代码拆分的方法(基于webpack) 基于simple_html_dom的使用小结 jQuery获取CSS样式中的颜色值的问题,不同浏览器格式不同的解决办法 使用javascript实现判断当前浏览器 JS实现根据当前文字选择返回被选中的文字 导入extjs、jquery 文件时$使用冲突问题解决方法 Python实现树莓派WiFi断线自动重连的实例代码 HTML5开发Kinect体感游戏的实例应用 php获取新浪微博数据API实例 MySQL中使用SQL语句查看某个表的编码方法 ajax的 IE cache 相关问题解决 lcx用法之心得总结(piracy) MAC系统快速启用缩放文件夹与Safari应用的方法 angular+webpack2实战例子 Bootstrap布局组件应用实例讲解 ASP语法高亮类代码 javascript SpiderMonkey中的函数序列化如何进行 jQuery 3.0中存在问题及解决办法 jquery 淡入淡出效果的简单实现 dede文章页面如何显示作者的头像默认只能显示作者用户名 JavaScript 闭包详细介绍 详解php魔术方法(Magic methods)的使用方法 php字符串比较函数用法小结(strcmp,strcasecmp,strnatcmp及strnatcasecmp) php缓冲 output_buffering和ob_start使用介绍 Python实现的中国剩余定理算法示例 jQuery使用Selectator插件实现多选下拉列表过滤框(附源码下载) 容器内存占用之系统cache介绍 深入分析MSSQL数据库中事务隔离级别和锁机制 js中通过split函数分割字符串成数组小例子 python调用百度语音识别api iPhone怎么录制屏幕?在Mac系统上录制iOS屏幕方法图解 jQuery on()绑定动态元素出现的问题小结 asp.net模板引擎Razor调用外部方法用法实例 Python微信公众号开发平台 微信小程序动态的加载数据实例代码 不用float实现div模块居中布局 [译]ASP.NET Core 2.0 路由引擎详解 javascript实现给定半径求出圆的面积 企业管理器备份和还原SQL Server数据库 JavaScript字符串对象charAt方法入门实例(用于取得指定位置的字符) .NET 刷新页面防止表单二次提交的实现方法 BootStrap入门教程(二)之固定的内置样式 vue-cli之router基本使用方法详解 Centos6.5和Centos7 php环境搭建方法 FCKeditor 网页在线编辑器的使用方法 vue插件开发之使用pdf.js实现手机端在线预览pdf文档的方法 FCKeditor smarty 编辑器的应用PHP ES6中箭头函数的定义与调用方式详解 python微信公众号之关键词自动回复 Extjs中DisplayField的日期或者数字格式化扩展 php使用变量动态创建类的对象用法示例 jQuery旋转插件jqueryrotate用法详解 [PHP]常用正则表达式收集 原生JavaScript编写俄罗斯方块 IOS10 隐私权限设置实例详解 BootStrap学习系列之Bootstrap Typeahead 组件实现百度下拉效果(续) 《CSS3实战》笔记--渐变设计(一) JavaScript的String字符串对象常用操作总结 Python数据处理numpy.median的实例讲解 mui框架移动开发初体验详解 用React加CSS3实现微信拆红包动画效果 win2003 VPS服务器之用IIS建立网站 详解.net mvc session失效问题 jQuery遍历Form示例代码 jQuery实现Twitter的自动文字补齐特效 D3.js封装文本实现自动换行和旋转平移等功能 jQuery插件zTree实现删除树节点的方法示例 在Django的通用视图中处理Context的方法 Android入门之使用eclipse进行源码开发的方法 python如何拆分含有多种分隔符的字符串 PHP删除数组中特定元素的两种方法 JS库particles.js创建超炫背景粒子插件(附源码下载) JavaScript入门教程(8) Location地址对象 python使用scrapy解析js示例 使用getBoundingClientRect方法实现简洁的sticky组件的方法 浅谈JavaScript函数的四种存在形态 Javascript排序算法之计数排序的实例 python爬取w3shcool的JQuery课程并且保存到本地 mac找不到蓝牙设备该怎么办? mac找不到蓝牙键盘的解决办法 URL重写及干掉ASP.NET试图状态的实现方法 ThinkPHP中RBAC类的四种用法分析 JavaScript阻止事件冒泡示例分享 JavaScript原生编写《飞机大战坦克》游戏完整实例 python微信公众号开发简单流程 jquery ajax jsonp跨域调用实例代码 Bootstrap Table快速完美搭建后台管理系统 js判断所有表单项不为空则提交表单的实现方法 Angular.js初始化之ng-app的自动绑定与手动绑定详解 jquery 获取自定义属性(attr和prop)的实现代码 BootStrap实现带关闭按钮功能 asp.net 网页动态查询条件的实现 利用jQuery实现WordPress中@的ID悬浮显示评论内容 EF 配置Oracle数据库的具体操作方法 Node.js中的http请求客户端示例(request client) Linux下的SVN服务器搭建步骤 奉献出一个封装的curl函数 便于调用(抓数据专用) Javascript实现登录记住用户名和密码功能 使用apidocJs快速生成在线文档的实例讲解 苹果电脑连不上WiFi 苹果mac电脑连不上无线网络 Python中的XML库4Suite Server的介绍 全文检索技术 sql server ajax三级联动实现代码 PHP无法访问远程mysql的问题分析及解决 javascript在IE下trim函数无法使用的解决方法 Node.js+jade抓取博客所有文章生成静态html文件的实例 详解CSS3中@media的实际使用 PHP三种方式实现链式操作详解 mysql5.7.19 解压版安装教程详解(附送纯净破解中文版SQLYog) ios基于UITableViewController实现列表 js判断选择的时间是否大于今天的代码 jQuery+css实现百度百科的页面导航效果 关于网站什么信息都需要审核的问题 Bootstrap 折叠(Collapse)插件用法实例详解 python中redis的安装和使用 JAVASCRIPT THIS详解 面向对象 js获取页面传来参数的方法 MySQL外键约束的禁用与启用命令 注册页面之前先验证用户名是否存在的php代码 vue初尝试--项目结构(推荐) spring boot + quartz集群搭建的完整步骤 jQuery simplePage+AJAX plus分页插件用法实例 python使用心得之获得github代码库列表 简单粗暴的Redis数据备份和恢复方法 vue删除html内容的标签样式实例 5步学会使用VideoView播放视频 JavaScript中number转换成string介绍 Java中使用LocalDate根据日期来计算年龄的实现方法 php实现cc攻击防御和防止快速刷新页面示例 小巧强大的jquery layer弹窗弹层插件 Redis实现多人多聊天室功能 CentOS搭建LAMP服务器环境硬盘分区方案分享 调整CSS类型的顺序改变链接翻滚效果 iOS实现简单的抽屉效果 iOS中实现动态区域裁剪图片功能实例 Python中使用异常处理来判断运行的操作系统平台方法 利用XMLHTTP实现的二级连动Select Javascript表格翻页效果的具体实现 .NET中RDLC循环处理数据的应用分析 jQuery控制div实现随滚动条滚动效果 php结合mysql与mysqli扩展处理事务的方法 MySQL与Oracle数据类型对应关系(表格形式) 浅谈Android Studio如何Debug对应so文件C_C++代码 Vue 使用 Mint UI 实现左滑删除效果CellSwipe JQuery实现动态适时改变字体颜色的方法 vue如何获取点击事件源的方法 javascript Slip.js实现整屏滑动的手机网页 详解iOS之关于double_float数据计算精度问题 window.location.href中url中数据量太大时的解决方法 JavaScript使用DeviceOne开发实战(四)仿优酷视频应用 ubuntu如何截图? ubuntu中截屏的三种方法 详解如何使用webpack在vue项目中写jsx语法 Ajax表单异步上传文件实例代码(包括文件域) Python统计单词出现的次数 asp.net 中静态方法和动态方法调用的区别实例分析 Uglifyjs(JS代码优化工具)入门 安装使用 linux 系统的一些使用小技巧 javascript组合使用构造函数模式和原型模式实例 详解使用路由延迟加载 Angular 模块 CentOS性能诊断工具命令集详解
css3用户体验注册表单.zip 基于 Java S2SH 框架开发的公司入职考试管理系统 微信小程序源码-微电商商城 Android例子源码动态绘制折线、圆柱、饼状图 【ASP.NET源码】圣诞许愿树源码_christmas.zip jquery全屏背景图片切换效果.zip 【PHP源码】博库CMS(BlogcoolCMS) v0.4_blogcoolcms.zip HTML5+CSS3+jQ注册表单.zip HTML5键盘控制PPT幻灯片演示代码.zip 带关闭左右切换的jquery选项卡.zip 【ASP.NET源码】dxbbs大侠论坛 v8.1 MSSQL build 0311_dxbbs81-mssql.zip HTML5 3D立方体按钮翻转特效.zip CSS3文字导航鼠标悬停显示气泡代码.zip jquery仿杂志翻页切换效果.zip CSS3带凹槽搜索框.zip jQuery鼠标点击手风琴展开特效.zip jQuery紫色不规则导航特效.zip js大幅下拉导航.zip jQuery tooltipster提示框代码.zip 帝国cms浅灰色模板.zip 微信小程序源码-生鲜商城 jQuery IOS风格提示通知层.zip 【PHP源码】仿163网盘无刷新文件上传 for PHP_fileupload_php.zip 大气宽屏公司官网模板.zip 夏日休闲度假旅游网站模板.zip jQuery京东商品筛选功能.zip 新网站即将推出HTML模板.zip 微信小程序 - 建材类.zip jQuery+CSS3遮罩弹出层动画代码.zip 纯css3波浪形菜单按钮.zip 纯CSS3彩色旋转加载动画特效.zip jQuery右下角美女在线客服代码.zip js 3D图片叠加旋转切换.zip jQuery产品图片360度旋转插件.zip jquery+css3垂直手风琴.zip 【ASP.NET源码】三层无存储过程分页Demo_3layerpager.zip jQuery鼠标响应式手风琴特效.zip 黑色炫酷企业项目展示模板.zip 定时收缩的jquery指示器特效.zip 专业工作室CSS网页模板.zip jquery椭圆边框下拉菜单.zip 【PHP源码】帝国备份王 v2.0正式版(MYSQL专业备份工具)_empirebak.zip 通用的iframe弹层插件.zip jQuery带背景切换登录注册表单.zip html5微信招聘信息动画切换代码.zip 纯CSS3实现3D太空飞船动画.zip 沙发家具公司网页模板.zip jQuery滑动拉伸导航按钮.zip jquery意见反馈和返回顶部.zip jQuery带次数的大转盘抽奖代码.zip jQuery滑动展开收缩手风琴代码.zip 可拖动查看大图jquery特效.zip 健身自行车运动网站模板.zip jQuery大气满屏焦点图切换.zip jQuery手机在线问答特效下载.zip jQuery动画弹出确认框和警告框.zip jquery拾色器插件iColor.zip 响应式html5模板 html5实现3D页面层叠切换效果.zip 扁平化设计师展示bootstrap模板.zip mongoDB从入门到上手视频教程 js+html5切木头手机游戏源码.zip 亲自购物wordpress主题.zip Joomla Underground.zip jQuery左侧固定导航栏插件stickySidebar.zip HTML5+CSS3+jQ注册表单.zip 站酷首页jQuery焦点图.zip jquery淡入淡出滑动幻灯片.zip js抖动美女相册图片放大展示.zip 弹性拖动交互切换特效.zip jquery矩形可拉伸导航.zip jQuery图片选中突出标签幻灯片代码.zip jquery图片无缝滚动.zip jQuery仿win10桌面QQ登录界面效果.zip Struts2+hibernate银行系统设计实现适合课程设计 jQ+HTML5视差滑动幻灯片.zip 时尚购物电子商务整站模板.zip 改图网左侧弹出二级导航jQuery.zip 淡绿色设计网页模板.zip jquery带下拉菜单和焦点图.zip 飘动下落的气球动画js特效.zip 【ASP.NET源码】华友商贸仿阿里巴巴B2B电子商务系统_hyb2b.zip jquery随机抽奖.zip HTML5全屏图文左右滑动切换特效.zip JAVA编程题全集(100题及答案) ssm+mysql后台管理框架 old boy-高级架构师 01、zabbix深度实践-13节 网站上线倒计时html5模板.zip jquery animated滑动切换分页显示代码.zip 雅虎中国首页全屏可伸缩可关闭广告代码.zip HTML5棕色背景新闻模板.zip 微信数据后台统计网站模板.zip jQuery仿阿里云购买日期选择代码.zip 【PHP源码】okphp Blog v4.1.1 Build 1224_okphpblog1224.zip jquery hover顶部导航栏菜单.zip 微信小程序源码-查火车票 苹果电子产品html模版.zip 微信小程序源码-交互操作控件 jQuery会员中心安全修改表单代码.zip Xenon扁平化bootstrap响应式win8后台模板源码 Java 网上购物商城源码下载 医院网站HTML模板下载.zip 花卉服务CSS网页模板.zip 15款手机端打开菜单动画过渡特效.zip 纯CSS3仿窗帘拉开关闭动画特效.zip 别墅房地产评估公司模板.zip 【PHP源码】php+mysql动态签名程序_iplogo.zip 仿药房网手机wap药店网站模板.zip jQuery游戏人物轮播展示切换代码.zip App开源分享-在路上项目源码 HTML5相册插件ma5gallery.zip 黑色风格汽车展示模板.zip Bootstrap时尚Nova网页设计模板.zip Fileupload测试demo jQuery双引号动态文本.zip HTML5完整版网页模板(超炫)全 当当网系统模板 Android 今日资讯源码 js图片相册弹出预览特效.zip JSP目录直读程序 30套网站模板 RSA加密算法BASE64,加密解密验签,Java实现Demo struts+hibernate+css+mysql 网上书店 【ASP.NET源码】RedSoft多层分布式架构实例源码_readsoft.zip jquery滑块多级下拉导航菜单.zip Java中国象棋 纯CSS3扁平垂直时间轴特效.zip jQuery+CSS桌面键盘打字特效.zip CSS3实现五点式图片放大镜.zip jQuery侧边栏隐藏滑动菜单代码.zip html5横向排列点击弹出切换特效.zip jquery鼠标悬浮高亮开关灯.zip jquery悬浮微信分享置顶特效.zip 《Axis实例与分析详解》.doc jQuery+CSS3扁平消息通知.zip css3鼠标经过突出显示详情特效.zip MSN左上角flash伸缩广告.zip CSS3小图标分享按钮.zip 微信小程序源码-天气预报 jquery Loading图片延迟加载特效.zip 微信小程序 - 写笔记带后端.zip 个性设计html模板下载.zip easyui demo 框架示例 棕色卡通帝国cms模板.zip jQuery五屏上下滚动焦点图.zip listview任意拖动排序 移动端简易jquery轮播图.zip JS动态波浪文字动画显示特效.zip js+html5实现图片倒影效果代码.zip 【PHP源码】GAODO网络商城购物系统_kgogomall.zip html5 svg左侧滑出手机聊天框代码.zip jquery鼠标点击自定义下拉框插件.zip Bootstrap Tabs选项卡代码.zip 宽屏摄影作品案例网页模板.zip Jsp客户关系管理CRM系统 【ASP.NET源码】房产中介网站系统源码_house.zip 仿中文幽默王手机wap笑话网站模板.zip 学生选课系统SSH框架实现 jquery仿FLASH筋斗云动态菜单.zip 【ASP.NET源码】TriptychBlog博客系统 v.9.0.6 汉化版_triptychblog_access.zip jquery点击按钮网格布局切换.zip JS模拟IOS联动插件iosselect.zip ssh2+easyui权限管理系统(人员、角色、权限) 企业网站CSS3网页模板.zip jquery表单获取短信验证码代码.zip jQuery+CSS3选择滑块按钮代码.zip 儿童游泳乐园网站模板.zip jQuery鼠标悬停图片控制文字切换.zip 动画组合画廊jQuery代码.zip jquery页面滚动顶部固定层代码.zip css3条纹边框效果.zip phpwind地宝门户新版风格.zip 网站后台管理静态页面及前台模板页面 仿春意盎然ecshop模板.zip jquery仿windows计算器.zip 个人博客html模板下载.zip jQuery 3D图片切换插件iPresenter.zip 绿色商务办公网站模板.zip 微信小程序 - 电影推荐.zip bay_news V1.0.0 北雨新闻信息管理系统 最全的eclipse快捷键大全 jquery坐标垂直滚动菜单.zip 图书管理系统(Java GUI实现) 粉色二级下拉菜单列表效果.zip 微信小程序源码-世博展会小程序 struts2.3.7-spring3.1.0-hibernate4.0.0 整合源码 jQ鼠标悬停图片上滑动显示说明.zip jquery实现微博分享评论表情.zip 微信小程序源码-人员招聘 Java爬虫+URL获取Img高宽 jQuery带播放暂停按钮进度条代码.zip 微信小程序源码-简易记账带后端 jQuery搜狗浏览器4.2专题页.zip 纯CSS3逼真三维球效果.zip 【T928】HTML5黑色响应式展台设计织梦dedecms整站模板(自适应).zip 红色砖头设计网站模板.zip 【PHP源码】SHUGUANG CMS企业网站管理系统 v1.0_shuguangcms.zip jQuery图文滑动切换.zip 水果蔬菜种植网站模板.zip 扫二维码、意见反馈、返回顶部三合一代码.zip
举报X