转载来自: http://www.cnblogs.com/fnng/p/3160606.html

Webdriver

Selenium 是 ThroughtWorks 一个强大的基于浏览器的开源自动化测试工具,它通常用来编写 Web 应用的自动化测试。

Selenium 2,又名 WebDriver,它的主要新功能是集成了 Selenium 1.0 以及 WebDriver​(WebDriver 曾经是 Selenium 的竞争对手)。也就是说 Selenium 2 是 Selenium 和 WebDriver 两个项目的合并,即 Selenium 2 兼容 Selenium,它既支持 Selenium API 也支持 WebDriver API。


下载安装:

下载地址(2015-06-04更新):https://pypi.python.org/packages/source/s/selenium/selenium-2.46.0.tar.gz#md5=6db65e1e7653da0fdc514df5db76d662

安装:

  1. setup.py install

简单示例:

  1. # -*- coding: UTF8 -*-
  2. from selenium import webdriver
  3. import time #调入time函数
  4. browser = webdriver.Firefox()
  5. url= 'http://email.163.com/#from=ntes_product'
  6. browser.get(url)
  7. browser.maximize_window() #将浏览器最大化显示
  8. browser.find_element_by_id("userNameIpt").send_keys("webdriver123")
  9. time.sleep(0.3) #休眠0.3秒
  10. browser.find_element_by_id("pwdPlaceholder").send_keys("webdriver321")
  11. browser.find_element_by_id("btnSubmit").click()
  12. time.sleep(5) #休眠5秒
  13. browser.find_element_by_css_selector("#dvNavTop ul li:nth-child(2)").click() # :nth-child(2)选取第几个标签,“2可以是你想要的数字”
  14. time.sleep(0.3) #休眠0.3秒
  15. browser.find_element_by_class_name("nui-editableAddr-ipt").send_keys('abc123@163.com')
  16. time.sleep(0.3) #休眠0.3秒
  17. browser.find_element_by_css_selector(".tH0 .nui-ipt-input").send_keys('test webdriver')
  18. time.sleep(0.3) #休眠0.3秒
  19. browser.find_element_by_class_name("APP-editor-iframe").send_keys('test webdriver content')
  20. time.sleep(0.3) #休眠0.3秒
  21. browser.find_element_by_css_selector(".jp0 .nui-btn-icon").click()
  22. time.sleep(0.3) #休眠0.3秒

说明:

引入webdriver

  1. from selenium import webdriver

操作浏览器 (浏览器可支持IE、Firefox、Chrome)

  1. browser = webdriver.Firefox()

然后通过模拟发送send_keys数据,模拟点击事件click(), 简单的示例是登录163邮箱,发送邮件。

为什么要添加time.sleep()? 因为要看脚本运行过程 、 因为页面没有加载完成,直接调取不存在元素会报错


对象属性

  1. browser.find_element_by_id("btnSubmit").click()

click()   :  模拟点击事件

  1. browser.quit() # or
  2. browser.close()

quit()close() 退出并关闭窗口的每一个相关的驱动程序

  1. browser.maximize_window()

maximize_window()   浏览器最大化

  1. browser.set_window_size(480, 800) #参数数字为像素点

set_window_size(480, 800)   设置浏览器固定宽、高

  1. browser.back()
  2. browser.forward()

back() 浏览器返回按钮操作,forward()  浏览器前进按钮操作

  1. js = "$('.logo').css('border', '1px solid red');"
  2. browser.execute_script(js)

execute_script() 执行js脚本

  1. browser.find_element_by_id("kw").clear()

clear() 用于清除输入框的内容,比如百度输入框里默认有个“请输入关键字”的信息,再比如我们的登陆框一般默认会有“账号”“密码”这样的默认信息。clear可以帮助我们清除这些信息。


简单对象的定位

对象的定位应该是自动化测试的核心,要想操作一个对象,首先应该识别这个对象。

定位对象的目的一般有下面几种

  • 操作对象
  • 获得对象的属性,如获得测试对象的class属性,name属性等等
  • 获得对象的text
  • 获得对象的数量

webdriver提供了一系列的对象定位方法,常用的有以下几种

  • id
  • name
  • class name
  • link text
  • partial link text
  • tag name
  • xpath
  • css selector
  1. #通过id方式定位
  2. browser.find_element_by_id("kw").send_keys("selenium")
  1. #通过name方式定位
  2. browser.find_element_by_name("wd").send_keys("selenium")
  1. #通过tag name方式定位
  2. browser.find_element_by_tag_name("input").send_keys("selenium")
  1. #通过class name 方式定位
  2. browser.find_element_by_class_name("s_ipt").send_keys("selenium")
  1. #通过CSS方式定位
  2. browser.find_element_by_css_selector("#kw").send_keys("selenium")
  1. #通过xphan方式定位
  2. browser.find_element_by_xpath("//input[@id='kw']").send_keys("selenium")
  1. #通过link 定位
  2. browser.find_element_by_link_text("贴 吧").click()
  1. #通过部分链接定位
  2. browser.find_element_by_partial_link_text("贴").click()

定位一组元素

webdriver可以很方便的使用findElement方法来定位某个特定的对象,不过有时候我们却需要定位一组对象,比如将页面上所有的checkbox都勾上。先获取一组对象,再在这组对象中过滤出需要具体定位的一些对象。比如定位出页面上所有的checkbox,然后选择最后一个。

第一种方法:

通过浏览器打个这个页面我们看到三个复选框和两个单选框。下面我们就来定位这三个复选框。

  1. # -*- coding: utf-8 -*-
  2. from selenium import webdriver
  3. import time
  4. import os
  5.  
  6. dr = webdriver.Firefox()
  7. file_path = 'file:///' + os.path.abspath('checkbox.html')
  8. dr.get(file_path)
  9.  
  10. # 选择页面上所有的input,然后从中过滤出所有的checkbox并勾选之
  11. inputs = dr.find_elements_by_tag_name('input')
  12. for input in inputs:
  13. if input.get_attribute('type') == 'checkbox':
  14. input.click()
  15. time.sleep(2)
  16.  
  17. dr.quit()

第二种定位方法:

  1. # -*- coding: utf-8 -*-
  2. from selenium import webdriver
  3. import time
  4. import os
  5.  
  6. dr = webdriver.Firefox()
  7. file_path = 'file:///' + os.path.abspath('checkbox.html')
  8. dr.get(file_path)
  9.  
  10. # 选择所有的checkbox并全部勾上
  11. checkboxes = dr.find_elements_by_css_selector('input[type=checkbox]')
  12. for checkbox in checkboxes:
  13. checkbox.click()
  14. time.sleep(2)
  15.  
  16. # 打印当前页面上有多少个checkbox
  17. print len(dr.find_elements_by_css_selector('input[type=checkbox]'))
  18. time.sleep(2)
  19.  
  20. dr.quit()

第二种写法与第一种写法差别不大,都是通过一个循环来勾选控件

  1. find_elements_by_css_selector(css_selector)
  1. #查找并返回多个元素的CSS 选择器列表

层级定位

在实际的测试中也经常会遇到这种问题:页面上有很多个属性基本相同的元素,现在需要具体定位到其中的一个。由于属性基本相当,所以在定位的时候会有些麻烦,这时候就需要用到层级定位。先定位父元素,然后再通过父元素定位子孙元素

  1. <html>
  2. <head>
  3. <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  4. <title>Level Locate</title>
  5. <script type="text/javascript" async="" src="jquery-1.9.1.min.js"></script>
  6. <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" />
  7. </head>
  8. <body>
  9. <h3>Level locate</h3>
  10. <div class="span3">
  11. <div class="well">
  12. <div class="dropdown">
  13. <a class="dropdown-toggle" data-toggle="dropdown" href="#">Link1</a>
  14. <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel" id="dropdown1" >
  15. <li><a tabindex="-1" href="#">Action</a></li>
  16. <li><a tabindex="-1" href="#">Another action</a></li>
  17. <li><a tabindex="-1" href="#">Something else here</a></li>
  18. <li class="divider"></li>
  19. <li><a tabindex="-1" href="#">Separated link</a></li>
  20. </ul>
  21. </div>
  22. </div>
  23. </div>
  24. <div class="span3">
  25. <div class="well">
  26. <div class="dropdown">
  27. <a class="dropdown-toggle" data-toggle="dropdown" href="#">Link2</a>
  28. <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel" >
  29. <li><a tabindex="-1" href="#">Action</a></li>
  30. <li><a tabindex="-1" href="#">Another action</a></li>
  31. <li><a tabindex="-1" href="#">Something else here</a></li>
  32. <li class="divider"></li>
  33. <li><a tabindex="-1" href="#">Separated link</a></li>
  34. </ul>
  35. </div>
  36. </div>
  37. </div>
  38. </body>
  39. <script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
  40. </html>

保存该文件,在浏览器打开:

这里自制了一个页面,上面有两个文字链接,点击两个链接会弹出一模一样的的两个下拉菜单,这两个菜单的属性基本一样。那么我如何区分找到相应的菜单项呢?

方法如下:

  1. # -*- coding: UTF8 -*-
  2. from selenium import webdriver
  3. import time
  4. import os
  5.  
  6. dr = webdriver.Firefox()
  7. file_path = 'file:///' + os.path.abspath('autohtml.html')
  8. dr.get(file_path)
  9.  
  10. #点击Link1链接(弹出下拉列表)
  11. dr.find_element_by_link_text('Link1').click()
  12. #在父亲元件下找到link为Action的子元素
  13. menu = dr.find_element_by_id('dropdown1').find_element_by_link_text('Action')
  14. #鼠标定位到子元素上
  15. webdriver.ActionChains(dr).move_to_element(menu).perform()
  16.  
  17. time.sleep(2)

class ActionChains(driver)

driver: 执行用户操作实例webdriver

生成用户的行为。所有的行动都存储在actionchains对象。通过perform()存储的行为。

move_to_element(menu)

移动鼠标到一个元素中,menu上面已经定义了他所指向的哪一个元素

to_element:元件移动到

perform()

执行所有存储的行为

需要我们日常工作中细细品味、慢慢消化这些函数的用法

效果:


元素操作

WebElement  另一些常用方法:

  • text  获取该元素的文本
  • submit  提交表单
  • get_attribute  获得属性值

text

  1. #id = cp 元素的文本信息
  2. data=driver.find_element_by_id("cp").text
  3. print data #打印信息

结果: ©2015 Baidu 使用百度前必读 意见反馈 京ICP证030173号

submit

  1. #通过submit() 来操作
  2. driver.find_element_by_id("su").submit()

这里用submit 与click的效果一样,我暂时还没想到只能用submit 不能用click的场景。

get_attribute

获得属性值

  1. select = driver.find_element_by_tag_name("select")
  2. allOptions = select.find_elements_by_tag_name("option")
  3. for option in allOptions:
  4. print "Value is: " + option.get_attribute("value")
  5. option.click()

多层框架或窗口的定位:

  • switch_to_frame()
  • switch_to_window()

对于一个现代的web应用,经常会出现框架(frame) 或窗口(window)的应用,这也就给我们的定位带来了一个难题。

有时候我们定位一个元素,定位器没有问题,但一直定位不了,这时候就要检查这个元素是否在一个frame中,seelnium  webdriver 提供了一个switch_to_frame方法,可以很轻松的来解决这个问题。

autohtml.html

  1. <html>
  2. <head>
  3. <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  4. <title>frame</title>
  5. <script type="text/javascript" async=""
  6. src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
  7. "></script>
  8. <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" />
  9. <script type="text/javascript">
  10. $(document).ready(function(){
  11. });
  12. </script>
  13. </head>
  14. <body>
  15. <div class="row-fluid">
  16. <div class="span10 well">
  17. <h3>frame</h3>
  18. <iframe id="f1" src="inner.html" width="800",
  19. height="600"></iframe>
  20. </div>
  21. </div>
  22. </body>
  23. <script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
  24. </html>

inner.html

  1. <html>
  2. <head>
  3. <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  4. <title>inner</title>
  5. </head>
  6. <body>
  7. <div class="row-fluid">
  8. <div class="span6 well">
  9. <h3>inner</h3>
  10. <iframe id="f2" src="http://www.baidu.com" width="700" height="500"></iframe>
  11. <a href="javascript:alert('watir-webdriver better thanselenium webdriver;')">click</a>
  12. </div>
  13. </div>
  14. </body>
  15. </html>

frame.html 中嵌套inner.html

switch_to_frame()

操作上面页面,代码如下:

  1. #coding=utf-8
  2. from selenium import webdriver
  3. import time
  4. import os
  5.  
  6. browser = webdriver.Firefox()
  7. file_path = 'file:///' + os.path.abspath('autohtml.html')
  8. browser.get(file_path)
  9.  
  10. browser.implicitly_wait(30) # 它的用法应该比time.sleep() 更智能,后者只能选择一个固定的时间的等待,前者可以在一个时间范围内智能的等待。
  11. '''
  12. 文档解释:
  13. selenium.webdriver.remote.webdriver.implicitly_wait(time_to_wait)
  14. 隐式地等待一个无素被发现或一个命令完成;这个方法每次会话只需要调用一次
  15. time_to_wait: 等待时间
  16. 用法:
  17. driver.implicitly_wait(30)
  18. '''
  19. #先找到到ifrome1(id = f1)
  20. browser.switch_to_frame("f1")
  21. #再找到其下面的ifrome2(id =f2)
  22. browser.switch_to_frame("f2")
  23.  
  24. #下面就可以正常的操作元素了
  25. browser.find_element_by_id("kw").send_keys("selenium")
  26. browser.find_element_by_id("su").click()
  27. time.sleep(3)

效果:

driver.switch_to_window()

有可能嵌套的不是框架,而是窗口,还有真对窗口的方法:switch_to_window

用法与switch_to_frame 相同:

driver.switch_to_window("windowName")


上传文件

上传过程一般要打开一个本地窗口,从窗口选择本地文件添加。所以,一般会卡在如何操作本地窗口添加上传文件。

其实,在selenium  webdriver 没我们想的那么复杂;只要定位上传按钮,通send_keys添加本地文件路径就可以了。绝对路径和相对路径都可以,关键是上传的文件存在

upload_file.html

  1. <html>
  2. <head>
  3. <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
  4. <title>upload_file</title>
  5. <script type="text/javascript" async="" src="jquery-1.9.1.min.js"></script>
  6. <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css"
  7. rel="stylesheet"/>
  8. <script type="text/javascript">
  9. </script>
  10. </head>
  11. <body>
  12. <div class="row-fluid">
  13. <form action="web.com" name="form1" method="post">
  14. <div class="span6 well">
  15. <h3>upload_file</h3>
  16. <input type="file" name="file"/>
  17. <input type="submit" value="提交" name="submit" id="submit" />
  18. </div>
  19. </form>
  20. </div>
  21. </body>
  22. <script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
  23. </html>

upload.py

  1. #coding=utf-8
  2. from selenium import webdriver
  3. import os,time
  4.  
  5. driver = webdriver.Firefox()
  6.  
  7. #脚本要与upload_file.html同一目录
  8. file_path = 'file:///' + os.path.abspath('autohtml.html')
  9. driver.get(file_path)
  10.  
  11. #定位上传按钮,添加本地文件
  12. driver.find_element_by_name("file").send_keys('D:\\upload_file.txt')
  13. time.sleep(10)
  14. driver.find_element_by_id("submit").click()
  15. time.sleep(2)

效果:


处理下拉框

下拉框是我们最常见的一种页面元素,对于一般的元素,我们只需要一次就定位,但下拉框里的内容需要进行两次定位,先定位到下拉框,再定位到下拉框内里的选项。

drop_down.html

  1. <html>
  2. <body>
  3. <select id="ShippingMethod" onchange="updateShipping(options[selectedIndex]);" name="ShippingMethod">
  4. <option value="12.51">UPS Next Day Air ==> $12.51</option>
  5. <option value="11.61">UPS Next Day Air Saver ==> $11.61</option>
  6. <option value="10.69">UPS 3 Day Select ==> $10.69</option>
  7. <option value="9.03">UPS 2nd Day Air ==> $9.03</option>
  8. <option value="8.34">UPS Ground ==> $8.34</option>
  9. <option value="9.25">USPS Priority Mail Insured ==> $9.25</option>
  10. <option value="7.45">USPS Priority Mail ==> $7.45</option>
  11. <option value="3.20" selected="">USPS First Class ==> $3.20</option>
  12. </select>
  13. </body>
  14. <script type="text/javascript" src="./jquery-1.9.1.min.js"></script>
  15. <script>
  16.  
  17. $("#ShippingMethod").change(function(){
  18. alert($(this).val()) ;
  19. });
  20.  
  21. </script>
  22. </html>

将上面的代码保存成html通过浏览器打开会看到一个最简单常见的下拉框,下拉列表有几个选项。

现在我们来选择下拉列表里的$10.69

  1. #-*-coding=utf-8
  2.  
  3. from selenium import webdriver
  4. import os,time
  5. driver= webdriver.Firefox()
  6. file_path = 'file:///' + os.path.abspath('drop_down.html')
  7. driver.get(file_path)
  8. time.sleep(2)
  9. m=driver.find_element_by_id("ShippingMethod")
  10. m.find_element_by_xpath("//option[@value='10.69']").click()
  11. time.sleep(2)
  12. driver.switch_to_alert().accept()

解析:

这里可能和之前的操作有所不同,首先要定位到下拉框的元素,然后选择下拉列表中的选项进行点击操作。

m=driver.find_element_by_id("ShippingMethod")

m.find_element_by_xpath("//option[@value='10.69']").click()

设置时会会弹出一个确定按钮;我们并没按照常规的方法去定位弹窗上的“确定”按钮,而是使用:

driver.switch_to_alert().accept()

完成了操作,这是因为弹窗比较是一个具有唯一性的警告信息,所以可以用这种简便的方法处理。

–  switch_to_alert()  

焦点集中到页面上的一个警告(提示)

– accept()
接受警告提示


Cookie处理

通过webdriver 操作cookie 是一件非常有意思的事儿,有时候我们需要了解浏览器中是否存在了某个cookie 信息,webdriver 可以帮助我们读取、添加,删除cookie信息。

打印cookie信息

  1. #coding=utf-8
  2.  
  3. from selenium import webdriver
  4. import time
  5.  
  6. driver = webdriver.Chrome()
  7. driver.get("http://www.youdao.com")
  8.  
  9. # 获得cookie信息
  10. cookie= driver.get_cookies()
  11.  
  12. #将获得cookie的信息打印
  13. print cookie
  14.  
  15. driver.quit()

运行打印信息:

  1. [{u'domain': u'.youdao.com', u'secure': False, u'value': u'aGFzbG9nZ2VkPXRydWU=', u'expiry': 1408430390.991375, u'path': u'/', u'name': u'_PREF_ANONYUSER__MYTH'}, {u'domain': u'.youdao.com', u'secure': False, u'value': u'1777851312@218.17.158.115', u'expiry': 2322974390.991376, u'path': u'/', u'name': u'OUTFOX_SEARCH_USER_ID'}, {u'path': u'/', u'domain': u'www.youdao.com', u'name': u'JSESSIONID', u'value': u'abcUX9zdw0minadIhtvcu', u'secure': False}]

对cookie的操作

上面的方式打印了所有cookie信息表,太多太乱,我们只想有真对性的打印自己想要的信息,看下面的例子

  1. #coding=utf-8
  2.  
  3. from selenium import webdriver
  4. import time
  5.  
  6. driver = webdriver.Firefox()
  7. driver.get("http://www.youdao.com")
  8.  
  9. #向cookie的name 和value添加会话信息。
  10. driver.add_cookie({'name':'key-aaaaaaa', 'value':'value-bbbb'})
  11.  
  12. #遍历cookies中的name 和value信息打印,当然还有上面添加的信息
  13. for cookie in driver.get_cookies():
  14. print "%s -> %s" % (cookie['name'], cookie['value'])
  15.  
  16. # 下面可以通过两种方式删除cookie
  17. # 删除一个特定的cookie
  18. driver.delete_cookie("CookieName")
  19. # 删除所有cookie
  20. driver.delete_all_cookies()
  21.  
  22. time.sleep(2)
  23. driver.close()

运行打印信息:

  1. YOUDAO_MOBILE_ACCESS_TYPE -> 1
  2. _PREF_ANONYUSER__MYTH -> aGFzbG9nZ2VkPXRydWU=
  3. OUTFOX_SEARCH_USER_ID -> -1046383847@218.17.158.115
  4. JSESSIONID -> abc7qSE_SBGsVgnVLBvcu
  5. key-aaaaaaa -> value-bbbb # 这一条是我们自己添加的

Python WebDriver自动化测试的更多相关文章

  1. 转来的——python webdriver自动化测试初步印象——转来的

    python webdriver自动化测试初步印象 以下示例演示启动firefox,浏览google.com,搜索Cheese,等待搜索结果,然后打印出搜索结果页的标题 from selenium i ...

  2. python webdriver 自动化测试练习 1-- 在线调查

    __author__ = 'Mickey0s' # coding:utf8 from selenium import webdriver from selenium.webdriver.common. ...

  3. 前端自动化测试python+webdriver

    前言:很多做测试的朋友的就知道,python+webdriver  可以做自动化测试,这对前端开发是非常有用的.  python 入门我就不讲了  ,推荐学习 廖雪峰老师的python入门3.5新版哈 ...

  4. 转:python webdriver API 之简单对象的定位

    对象(元素)的定位和操作是自动化测试的核心部分,其中操作又是建立在定位的基础上的,因此元素定位就显得非常重要. (本书中用到的对象与元素同为一个事物)一个对象就像是一个人,他会有各种的特征(属性) , ...

  5. 转:python webdriver 环境搭建

    第一节 环境搭建准备工具如下:-------------------------------------------------------------下载 python[python 开发环境]ht ...

  6. python selenium 自动化测试web

    如何使用python完成自动化测试web页面呢?首选selenium   那基于python的selenium如何使用,下面看一段测试案例: 基于python的selenium 安装方法: pip i ...

  7. 基于Appium、Python的自动化测试

    基于Appium.Python的自动化测试环境部署和实践   第一章 导言 1.1 编制目的 该文档为选用Appium作为移动设备原生(Native).混合(Hybrid).移动Web(Mobile ...

  8. [转]构建Python+Selenium2自动化测试环境(二)

    构建Python+Selenium2自动化测试环境完成之后,就需要测试支持python的selenium的版本是否都支持在不同浏览器上运行,当前我们分别在三个最通用的浏览器上通过脚本来测试. 1.在I ...

  9. Python Web自动化测试入门与实战,从入门到入行

    Python Web自动化测试入门与实战 购买地址 · 京东:https://item.jd.com/69239480564.html   天猫:https://detail.tmall.com/it ...

随机推荐

  1. TypeScript Declaration Merging(声明合并)

    TypeScript中有一些独特的概念,来自需要描述JavaScript对象类型发生了哪些变化.举个例子,最为独特的概念就是"声明合并".理解了这个概念将会对你在当前JavaScr ...

  2. 在github上搭建hexo博客

    准备工作 安装git 系统是win10家庭版,采用git v1.9.5版本,比较简单,一路next直到finsh完成安装. 安装node.js hexo是基于node.js驱动的一款快速.简单且功能强 ...

  3. DD_belatedPNG.js解决透明PNG图片背景灰色问题

    <!--[]> <script type="text/javascript" src="http://www.phpddt.com/usr/themes ...

  4. Git 学习笔记参考

    1.参考学习资料 网上资料: http://www.cnblogs.com/aoguren/p/4189086.html http://www.liaoxuefeng.com/wiki/0013739 ...

  5. js 闭包 理解

    1.什么是闭包 定义:是指有权访问另一个函数作用域中的变量的函数 创建闭包:在一个函数内部创建另一个函数 基本特点 在返回的匿名函数中 可以调用外部函数的变量 如下例中所示 内部函数(匿名函数) 可以 ...

  6. WinPcap4.13无法安装解决方法

    360软件管家提示把WinPcap更新至版本:4.1.0.2980,于是把旧版下载后,可新版本怎么也无法顺利安装,出现以下信息,旧版本已安装,关闭所有winpcap-based应用程序和再次运行安装程 ...

  7. webstorm常用快捷键

    常用快捷键—Webstorm入门 提高代码编写效率,离不开快捷键的使用,Webstorm拥有丰富的代码快速编辑功能,你可以自由配置功能快捷键. 快捷键配置 点击“File”-> “setting ...

  8. [NHibernate]并发控制

    目录 写在前面 文档与系列文章 并发控制 乐观并发控制(Optimistic Concurrency) 一个例子 悲观并发控制(Pessimistic Concurrency) 总结 写在前面 上篇文 ...

  9. BASH_SUBSHELL 变量不生效的情况

    BASH_SUBSHELL 实现于 Bash 3.0,我一直想不到它在实际编码中有什么用,后来在 Bash 的 Change Log 里找到一句话,才知道它是作调试用的: New variables ...

  10. 搭建XMPP学习环境

    XMPP(Extensible Messaging and Presence Protocol,前称Jabber)是一种以XML为基础的开放式IM协议.xmpp被人熟知,google talk肯定有一 ...