辰迅云帮助中心

其他类

这篇文章给大家分享的是有关javascript中Hoisting的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。简介“变量提升”意味着变量和函数的声明会在物理层面移动到代码的最前面,但这么说并不准确。 实际上变量和函数声明在代码里的位置是不会动的,而是在编译阶段被放入内存中。声明变量的方法var、let、const 不用以上关键字直接赋值的变量会挂载与windows环境下;let a=9const a=1var a=6c=5声明函数的方法javascript中声明函数的方法有两种:函数声明式和函数表达式。//函数声明function say(){   console.log('hello')  }//函数表达式var say=function (){   console.log('hello')  }提升的好处JavaScript 在执行任何代码段之前,将函数声明放入内存中的优点之一是,这允许你可以在在声明该函数之前使用一个函数。/*** 正确的方式:先声明函数,再调用函数 (最佳实践)*/function catName(name) {   console.log("我的猫名叫 " + name); } catName("Tigger");/*以上代码的执行结果是: "我的猫名叫 Tigger"*//*** 不推荐的方式:先调用函数,再声明函数 */catName("Chloe");function catName(name) {   console.log("我的猫名叫 " + name); }/*代码执行的结果是: "我的猫名叫 Chloe"*/提升规则var 声明的变量,提升时只声明,不赋值,默认为undefined;不用关键字直接赋值的变量不存在提升(demo1)函数提升会连带函数体一起提升,不执行;(deom2)预解析的顺序是从上到下;(demo4)函数的优先级高于变量,函数声明提前到当前作用域最顶端;(deom3)变量重名,提升时不会重复定义;在执行阶段后面赋值的会覆盖上面的赋值;(demo4)函数重名,提升时后面的会覆盖前面;(demo5)函数和变量重名,提升函数,不会重复定义,变量不会覆盖函数;在执行阶段后面赋值的会覆盖上面的赋值;(demo8)用函数表达式声明函数,会按照声明变量规则进行提升;(deom6)函数执行时,函数内部的变量声明和函数声明也按照以上规则进行提升;(deom7)let、const不存在提升;(demo9、demo10)/**demo1**/console.log('a=',a) //a=undefinedconsole.log('b=',b) // Uncaught ReferenceError: b is not definedvar a=1b=6/**deom2**/console.log('a=',a) // a=function a() {console.log("func a()")}function a() {console.log("func a()") }/**deom3**/console.log('a=',a) // a=function a() {console.log("fun a")}var a=3var a=4function a(){console.log("fun a") }var a=5var a=6console.log("a=",a) // a=6 /**deom4**/console.log('a=',a) // a=undefinedvar a =2console.log('a=',a) //var a =3var a =4console.log('a=',a) // a=4console.log('b=',b) //b= undefinedvar b='b1'/**deom5**/console.log('a=',a) // a=function a() {console.log("a2")}function a(){console.log("a1") }function a(){console.log("a2") }console.log('a=',a) // a=function a() {console.log("a2")}/**deom6**/console.log('a=',a) // a=undefinedvar a=function(){console.log('a1')}var a=3var a=4var a=5console.log(a)var a=function(){console.log('a2')}console.log('a=',a) // a= ƒ (){console.log('a2')}/**deom7**/console.log('b=',b)var a=3function b(i){   console.log('a=',a)   var a=4  function a(){     console.log('fun a')   }   console.log('a=',a) } b()/**demo8**/console.log('a=',a) //a= function a(){ console.log('fun a')}var a=2function a(){   console.log('fun a') }console.log('a=',a) // a=2var a=3var a=4var a=5console.log('a=',a) // a=5/**demo9**/console.log('a=',a) //Uncaught ReferenceError: a is not definedlet a=4/****/<!--demo10-->console.log('b=',b) // Uncaught ReferenceError: b is not definedconst b=5感谢各位的阅读!关于“javascript中Hoisting的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!...

这篇文章将为大家详细讲解有关如何使用函数式编程对JavaScript进行断舍离,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。关于DHTMLDHTML是Dynamic HTML的简称,就是动态的html(标准通用标记语言下的一个应用),是相对传统的静态的html而言的一种制作网页的概念。所谓动态HTML(Dynamic HTML,简称DHTML),其实并不是一门新的语言,它只是HTML、CSS和客户端脚本的一种集成,即一个页面中包括html+css+javascript(或其它客户端脚本),其中css和客户端脚本是直接在页面上写而不是链接上相关文件。在那个时候,JavaScript的演化很慢,主要应用在表单验证。因此,不像今天这么火爆,并没有引起太多的关注。可以说只是一个锦上添花的附加物,你需要确保在浏览器禁用JavaScript之后,你的应用依然可以正常使用。再往后,框架一个接着一个出现:jQuery,Knockout, Angular, React, Vue, 等等。同样,JavaScript也在加速演化。我们才使用ES6不久,现在人们几乎已经跳过ES7,开始讨论ES8了。并且,我们有很多替代品,比如TypeScript,CoffeScript,ClojureScript, ELM,等等。我们已经被太多的框架和语言所淹没,很难去跟踪和掌握所有的语言和框架。错误路线当JavaScript逐渐成熟,面向对象编程(OOP)的概念也渗入进来,而且我曾经很喜欢。我开始尝试所有不同的方法来创建类,我最终也可以正确的使用继承。我对自己说:JavaScript开始真的像一个语言了!但是,直到多年以后我发现OOP是JavaScript引入的最糟糕的一个设计!我尝试将我对C#的理解带入到JavaScript中去。一开始充满期待,但是后来发现真的太复杂,太烧脑了。这主要是因为JavaScript的原型继承和C#不一样,我已经习惯于每天编写类似于console.log(this)这样飘逸的代码。但是现在呢?如果我一不小心没按照规则来,那将会给我带来噩梦。私有方法和私有值必须要在名字前面加上下划线,甚至必须用闭包来保证私有性。因此,不仅OOP导致了很多问题,同时也由于添加OOP带来了很多新的问题。函数式编程一开始我并不理解。我可以阅读并理解这些用函数式编写的代码,但是不知道为什么!最终,我强迫我自己去学习它。函数式语言给了我一个全新的视角,让我从一个完全不同的方式去看待编程。一开始会感到不自然,需要时间去适应。所有的定义都是基于函数,值不可更改,无状态。我用函数式的思维去解决问题。因为不熟悉,我花了更长的时间去学习。渐渐地,我熟练掌握了使用函数式的方法去编程。并且,我也知道所有代码这样编写的内在含义。我的代码更加简洁了,而且容易复用。渐渐的,我以前使用的那些语言特性从代码中消失了,我的代码看上去完像是用另一个语言编写。我还在用JavaScript吗?1. 不再使用var我用const替代了var。通过函数式的设计,我的函数都是纯(pure)的。不会再去对一个变量进行值的变更操作,同样也是为了确保不会对其操作。我会检查代码确保每一个var,甚至let,所有声明都使用const。2. 没有for循环在学习程序语言的时候,我们一开始就会学到for循环。但是自从学习了函数式编程,我将for循环都改成了使用filter, map和reduce来实现。对于那些需要一些额外计算的需求,我会使用递归或则第三方库比如lazy.js。如今我的代码里面完全没有for循环了,如果你看到了,告诉我我会把它消除。3. if也可以被简化我开始停止在if里面编写大块大块的代码。我将里面的逻辑抽取出来单独放在一个函数中。这样,我们就可以将if用三元算子(a?b:c)来简化。如今我的代码里面几乎没有if语句。为了方便其他开发者理解我的代码,我很少使用它。4. 和switch说拜拜同样,我也不喜欢用switch,而是寻找一个函数式的写法。我也很喜欢用Ramda的cond算子来替代swtich。5. 不在担心this对的,你没有听错!我们也可以完全消除this。函数式的JavaScript可以让你完全抛弃使用烦人的this现在只有数据和函数,甚至数据不过是函数的一种特殊表达形式,你再也不需要this了。我开始将对象理解为函数式语言中状态(state)和函数。我甚至不需要把状态或则函数和对象绑定到一起,就像OOP中那样。面向对象的设计不是必须的现在往回看,我发现面型对象编程带来的复杂度真的是不必要的。我可以使用函数式语言实现同样的功能,完成相同的任务。而且,代码更加轻简,因为不在需要将这些复杂的对象传来传去。只有数据和函数,而且因为函数没有和对象绑定,更加容易复用。我不在需要担心传统的原型继承带来的所有的问题,JavaScript设计的并不好。JavaScript缺乏私有、公有、内部或则被保护这类访问控制器也不再是一个问题。访问控制器是用来解决由于引入面向对象编程而设计的。在函数式的JavaScript中,这些问题不复存在。总结我的代码现在看上去完全不同。它包含了很多纯函数,我将它们做成不同的ES6模块。这些函数可以被使用来构建更加复杂的函数。很大一部分函数都是很简单的一行lambda表达式。现在我看待软件的思维也变了:输入是一个数据流,然后程序作用到该数据流上对数据进行各种操作,然后返回新的数据。函数式设计对程序语言的影响以及无处不在,C#中的LINQ就是一个最佳的例子。同样Java 8也引入了函数式语言的特性。关于“如何使用函数式编程对JavaScript进行断舍离”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。...

小编给大家分享一下基于vue2.0动态组件及render怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!如下所示:<template> <div class="hello"> <h2>{{ msg }}</h2> <h3>这里是Boor</h3> <component v-bind:my-data="items" v-bind:is="currentView">  <!-- 组件在 vm.currentview 变化时改变! --> </component> <a class="explain">直直</a> <button v-on:click="addData">点击</button> </div></template><script> //import $ from '@/assets/scripts/lib/zepto.min' //console.log($); //import Vue from 'vue' function isEmptyObject(e) {  var t;  for (t in e)   return !1;  return !0 }  function objectLength(o) {   var len = 0;   for(var p in o) {    len++;   }   return len;  }  let data ={   c_0:{c:1},   c_1:{c:2},   c_2:{c:3},   c_3:{c:4}  };  let num = 0;  //console.log(objectLength(data)); const MyComponent = {  //template: '<h4 v-for="item in items">{{ item.c}}</h4>', props: ['myData'],  data(){   return{   //items : myData  }  },  render: function (createElement) {   debugger;   let items = this.myData;    //items = JSON.stringify(items);  let num = objectLength(items);  if (!isEmptyObject(items)) {   debugger;   return createElement('div', Array.apply(null, { length: num }).map(function (v,index) {   return createElement('h4', items['c_'+index]['c'].toString())   }))  } else {   return createElement('h2', '没有数据!');  }  }  };  // 注册 //Vue.component('my-component', MyComponent);export default {  name: 'bar',  data () {  return {   msg: 'Bar',   fuck: 'Hello',   items: data,   currentView: MyComponent  }  },  methods:{  addData : function(){   for(let p in data) {    if(p == 'c_'+num) {     data[p] = {'c': num };    } else {     data['c'+num] = {'c': num };    }   }   num++;  }  } };</script><!-- Add "scoped" attribute to limit CSS to this component only --><style scoped>h2, h3 {  font-weight: normal; }ul {  list-style-type: none;  padding: 0; }li {  display: inline-block;  margin: 0 10px; }a {  color: #42b983; }</style>以上是“基于vue2.0动态组件及render怎么用”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注辰迅云云资讯频道!...

小编给大家分享一下Scratch3.0如何实现页面初始化并同时加载sb3文件,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!scratch是一种非常合适的培养自己的编程兴趣的方式。通过拖拽的方式,可以实现一些游戏,小程序的开发,就像搭积木一样目标文件地址:src\containers\sb-file-uploader.jsx修改 sb-file-uploader.jsx文件, class SBFileUploader中添加componentDidMount(),代码如下componentDidMount() {      var _this = this; // 作品所在存放地址 var sb3Path = null; /**  * 必须使用 $(window).on("load",function(){});  * 否则页面在未加载完的情况下,有些组件会来不及加载,影响二次文件保存  */ console.log("尚未初始加载Sb3文件"); $(window).on("load",function(){ console.log("即将初始加载Sb3文件"); let reader = new FileReader(); let request = new XMLHttpRequest(); console.log("加载的资源路径", sb3Path); request.open('GET', sb3Path, true); request.responseType = "blob"; request.onload = function() { if(request.status==404){ alert("未找到sb3类型的资源文件"); location.href='/scratch'; } let blobs = request.response reader.readAsArrayBuffer(blobs); reader.onload = () => _this.props.vm.loadProject(reader.result).then(() => { analytics.event({ category: 'project', action: 'Import Project File', nonInteraction: true }); _this.props.onLoadingFinished(_this.props.loadingState); }).catch(error => { log.warn(error); }); } request.send(); }); }目标文件地址:src\components\menu-bar\menu-bar.jsx修改 menu-bar.jsx文件, class MenuBar 中初始SBFileUploader,代码如下// 必须加载这个文件import SBFileUploader from '../../containers/sb-file-uploader.jsx';class MenuBar extends React.Component {         render () {              return (             <Box                 className={classNames(                     this.props.className,                     styles.menuBar,                     {[styles.saveInProgress]: this.props.isUpdating}                 )}             > <SBFileUploader onUpdateProjectTitle={PropTypes.func} /** 初始化加载文件到项目 **/> {(className, renderFileInput, loadProject) => ( <button onClick={loadProject} className={classNames(styles.scratchHide)}></button> )} </SBFileUploader>             </Box>         );     } } export default injectIntl(connect(     mapStateToProps,     mapDispatchToProps )(MenuBar));以上是“Scratch3.0如何实现页面初始化并同时加载sb3文件”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注辰迅云资讯频道!...

如何在Bash中编写函数

2021/8/17 22:08:05

本篇内容主要讲解“如何在Bash中编写函数”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何在Bash中编写函数”吧!通过编写函数来减少代码的冗余和维护。在编程时,实际上是在定义要由计算机执行的过程procedure或例程routine。一个简单的类比是将计算机编程与烤面包进行比较:你一次列出了要组建工作环境的配料,然后列出了烤面包所必须采取的步骤。在编程和烘烤中,必须以不同的间隔重复执行某些步骤。例如,在烤面包中,这可能是酵母培养的过程:STIR=100SNOOZE=86400 function feed_culture {   remove_from(pantry)   add(flour, water)   stir($STIR)   sleep($SNOOZE) }然后,揉面和醒发面团:KNEAD=600SNOOZE=7200 function process_dough {   remove_from(proofing_drawer)   knead($KNEAD)   return_to_drawer($SNOOZE) }在编程中,这些子例程subroutines可以表示为函数function。函数对程序员很重要,因为它们有助于减少代码中的冗余,从而减少了所需的维护量。例如,在以编程方式烤制面包的假想场景中,如果你需要更改面团醒发的用时,只要你之前使用函数,那么你只需更改一次用时,或使用变量(在示例代码中为 SNOOZE)或直接在处理面团的子程序中更改用时。这样可以节省你很多时间,因为你不必通过你的代码库遍历每个可能正在醒发的面团,更不用说担心错过一个。许多 bug 是由未更改的缺失的值或执行不正确的 sed  命令引起的,它们希望捕获所有可能而不必手动寻找。在 Bash 中,无论是在编写的 脚本或在独立的文件中,定义函数和使用它们一样简单。如果将函数保存到独立的文件中。那么可以将它 source 到 脚本中,就像 include C 语言或 C++ 中的库或将模块 import 到 Python 中一样。要创建一个 Bash 函数,请使用关键字 function:function foo {# code here}这是一个如何在函数中使用参数的例子(有些人为设计,因此可能会更简单):#!/usr/bin/env bashARG=$1 function mimic {   if [[ -z $ARG ]]; then    ARG='world'  fi  echo "hello $ARG"}   mimic $ARG结果如下:$ ./mimic hello world $ ./mimic everybody hello everybody请注意脚本的最后一行,它会执行该函数。对于编写脚本的新手来说,这是一个普遍的困惑点:函数不会自动执行。它们作为潜在的例程存在,直到被调用。如果没有调用该函数,那么函数只是被定义,并且永远不会运行。如果你刚接触 Bash,请尝试在包含最后一行的情况下执行示例脚本一次,然后在注释掉最后一行的情况下再次执行示例脚本。使用函数即使对于简单的脚本,函数也是很重要的编程概念。你越适应函数,在面对一个不仅需要声明性的 命令行,还需要更多动态的复杂问题时,你就会越容易。将通用函数保存在单独的文件中还可以节省一些工作,因为它将帮助你建立常用的程序,以便你可以在项目间重用它们。看看你的脚本习惯,看是否适合使用函数。到此,相信大家对“如何在Bash中编写函数”有了更深的了解,不妨来实际操作一番吧!这里是辰迅云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!...

这篇文章给大家分享的是有关Python中可迭代对象、迭代器、For循环工作机制、生成器的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1.iterable iterator区别要了解两者区别,先要了解一下迭代器协议:迭代器协议是指:对象需要提供__next__()方法,它返回迭代中的元素,在没有更多元素后,抛出StopIteration异常,终止迭代。可迭代对象就是:实现了迭代器协议的对象。协议是一种约定,可迭代对象实现迭代器协议,Python的内置工具(如for循环,sum,min,max函数等)通过迭代器协议访问对象,因此,for循环并不需要知道对象具体是什么,只需要知道对象能够实现迭代器协议即可。迭代器(iterator)与可迭代对象(iterable)并不是同一个概念。直观上:1.可迭代对象(iterable):凡是具有__iter__的方法的类,都是可迭代的类。可迭代类创建的对象实现了__iter__方法,因此就是可迭代对象。用list、tuple等容器创建的对象,都是可迭代对象。可迭代对象通过__iter__方法返回一个迭代器,然后在内部调用__next__方法进行迭代,最后没有元素时,抛出异常(这个异常python自己会处理,不会让开发者看见)。2.迭代器(iterator):迭代器对象必须同时实现__iter__和__next__方法才是迭代器。对于迭代器来说,__iter__ 返回的是它自身 self,__next__ 则是返回迭代器中的下一个值,最后没有元素时,抛出异常(异常可以被开发者看到)。从上面2点可以看出:1.迭代器一定是可迭代对象,因为它实现了__iter__()方法;2.通过iter()方法(在类的内部就是__iter__)能够使一个可迭代对象返回一个迭代器。3.迭代器的 __iter__ 方法返回的是自身,并不产生新的迭代器对象。而可迭代对象的 __iter__ 方法通常会返回一个新的迭代器对象。第3点性质正是可迭代对象可以重复遍历的原因(每次返回一个独立的迭代器,就可以保证不同的迭代过程不会互相影响);而迭代器由于返回自身,因此只能遍历一次。上面3点可以通过下面的例子看出来:from collections import Iterablefrom collections import Iteratorprint isinstance(iter([1,2]),Iterator)print isinstance(iter([1,2]),Iterable)print isinstance([1,2],Iterator)print isinstance([1,2],Iterable)##resultTrueTrueFalseTrue##id可以查看一个对象在内存中的地址test=[1,2,3] testIter=iter(test)print id(testIter)print id(testIter)print id(iter(test))print id(iter(test))print id(test.__iter__())print id(test.__iter__())##result:可迭代对象每次调用iter方法都会返回一个新的迭代器对象,而迭代器对象调用iter方法返回自身67162576 67162576 67162688 67162632 67162856 671630242.iterable的工作机制拿一个例子看看,首先定义一个有__iter__方法,但是没有next()方法的类 (PS:在python2中是next(),python3是__next__()):from collections import Iterable, Iteratorclass Student(object): def __init__(self,score): self.score=score  def __iter__(self): return iter(self.score)   test= Student([80,90,95])print isinstance(test, Iterable)print isinstance(test, Iterator)for i in test:  print i##resultTrueFalse809095##可重复遍历for i in test:  print i##result809095上面代码的结果印证了定义中提到的:缺少了next()方法,可迭代对象就不是迭代器。此外,注意到:可迭代对象通过__iter__方法每次都返回了一个独立的迭代器,这样就可以保证不同的迭代过程不会互相影响。也就是说,通过iterable可以实现重复遍历,而迭代器是无法重复遍历的!因此,如果想要把可迭代对象转变为迭代器,可以先调用iter()方法返回一个迭代器。然后就可以用next()不断迭代了!print isinstance(iter(test),Iterator) testIter=iter(test)print testIter.next()print testIter.next()print testIter.next()##resultTrue 80 90 95##一旦取完了可迭代对象中所有的元素,再次调用next就会发生异常print testIter.next()##resultStopIteration:3.迭代器Iterator的工作机制看下面这个例子:class Student(object): def __init__(self,score):  self.score=score  def __iter__(self):  return self   def next(self):  if self.score<100:  self.score+=1 return self.score  else: raise StopIteration()   test= Student(90) print isinstance(test, Iterable) print isinstance(test, Iterator) print test.next() print test.next() print test.next()for i in test: print i##resultTrue True919293949596979899100##如果此时再对test这个迭代器调用next方法,就会抛出异常test.next()##resultStopIteration:这个例子印证了定义中的:迭代器对象必须同时实现__iter__和__next__方法才是迭代器。那么,使用迭代器好处在哪呢?Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。一个很常见的应用就是:Python在处理列表的时候,是直接把整个列表读进内存的,当遇到大量样本时的时候会变得很慢。而迭代器的优势在于只把需要的元素读进内存,因此占用内存更少。换句话说,迭代器是一种惰性求值模式,它是有状态的,只有在调用时才返回值,没有调用的时候就等待下一次调用。这样就节省了大量内存空间。这个例子印证了定义中的:迭代器对象必须同时实现__iter__和__next__方法才是迭代器。那么,使用迭代器好处在哪呢?Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。一个很常见的应用就是:Python在处理列表的时候,是直接把整个列表读进内存的,当遇到大量样本时的时候会变得很慢。而迭代器的优势在于只把需要的元素读进内存,因此占用内存更少。换句话说,迭代器是一种惰性求值模式,它是有状态的,只有在调用时才返回值,没有调用的时候就等待下一次调用。这样就节省了大量内存空间。4.for循环的工作机制有了上面2个例子,就可以总结一下在可迭代对象与迭代器中的For循环工作机制了。当对象本身就是迭代器时,For循环工作机制:调用 __iter__方法,返回自身self,也就是返回迭代器。不断地调用迭代器的next()方法,每次按序返回迭代器中的一个值。迭代到最后没有元素时,就抛出异常 StopIteration在可迭代对象中,for循环工作机制:先判断对象是否为可迭代对象(等价于判断有没有__iter__或__getitem__方法),没有的话直接报错,抛出TypeError异常。有的话,调用 __iter__方法,返回一个迭代器。在python内部不断地调用迭代器的__next__方法,每次按序返回迭代器中的一个值。迭代到最后没有元素时,就抛出异常 StopIteration,这个异常 python 自己会处理,不会暴露给开发者。借用网络上的一张图直观理解一下:此外,还要注意,python中的for循环其实兼容了两种机制:如果对象有__iter__会返回一个迭代器。如果对象没有__iter__,但是实现了__getitem__,会改用下标迭代的方式。__getitem__可以帮助一个对象进行取数和切片操作。当for发现没有__iter__但是有__getitem__的时候,会从0开始依次读取相应的下标,直到发生IndexError为止,这是一种旧的迭代协议。iter方法也会处理这种情况,在不存在__iter__的时候,返回一个下标迭代的iterator对象来代替。一个重要的例子是str,字符串就是没有__iter__方法的,但是却依然可以迭代,原因就是其在for循环时调用了__getitem__方法。看一个例子:from collections import Iterable, Iteratorclass Student(object): def __init__(self,score): self.score=score  def __getitem__(self,n): return self.score[n]   test= Student([80,90,95])print isinstance(test, Iterable)print isinstance(test, Iterator)print isinstance(iter(test), Iterable)print isinstance(iter(test), Iterator)for i in test:  print i##resultFalseFalseTrueTrue809095for i in range(0,3):  print test[i]##result809095for i in iter(test):  print i##result809095可以看到,实现了__getitem__方法的对象本身,尽管不是iterable与iterator,仍旧是可以调用for循环的。通过iter方法,返回一个下标迭代的iterator对象。5.generator的原理最后说一下生成器,生成器是一种特殊的迭代器,当然也是可迭代对象。对于生成器,Python会自动实现迭代器协议,以便应用到迭代中(如for循环,sum函数)。由于生成器自动实现了迭代器协议,所以,我们可以调用它的next方法,并且,在没有值可以返回的时候,生成器自动产生StopIteration异常。创建生成器的方法:将return 改为yield。具体的实现网络上教程很多,不细说了。6.总结到一幅图片很好的描述了本文的所有内容,就拿它作为文末的总结吧!感谢各位的阅读!关于“Python中可迭代对象、迭代器、For循环工作机制、生成器的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!...

这篇文章主要为大家展示了“javascript怎么颠倒元素位置”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“javascript怎么颠倒元素位置”这篇文章吧。首先我们来看一个小例子。<script>var arr = new Array(3);  arr[0] = "one"; arr[1] = "two"; arr[2] = "three";console.log(arr);console.log(arr.reverse());console.log(arr);</script>这个小例子的结果是我们看看这个结果,第一个结果是很正常的,就是我们定义的,没有问题,第二个结果就开始有点意思了,他被反着输出来了,第三个的结果也很有意思,原本以为会按原数组输出,居然没有,看来这个有点东西啊。这个结果里,我们将数组里的元素“["one", "two", "three"]”反着“["three", "two", "one"]”输出了。看来javascript中真的有将元素颠倒位置的方法啊。那我们可需要好好学习这个方法啦。这个方法的名称叫做reverse。reverse()方法用于颠倒数组中元素的顺序。再来看上面这个例子,我们第一次输出arr这个数组的时候,它是按照我们定义的来输出的。然后当我们使用reverse()这个方法之后,再输出arr这个数组,它就会按照我们颠倒数组后元素的顺序来输出。所以我们可以得出一个结论:该方法会改变原来的数组,而不会创建新的数组。现在我们就来学习一下这个方法的语法格式吧,加深一下印象。数组对象.reverse()以上是“javascript怎么颠倒元素位置”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注辰讯云资讯频道!...

网站怎么阻止网络爬虫

2021/8/16 22:30:19

这篇文章主要为大家展示了“网站怎么阻止网络爬虫”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“网站怎么阻止网络爬虫”这篇文章吧。两种主要方法可以阻止爬虫:1.屏蔽它的 IP 地址。收集爬虫的所有 IP (这可能没什么难度),并将它们添加到您的网络服务器、防火墙或任何其他您可能正在使用的软件或服务的黑名单中保护您的网站。有了这种块,爬虫甚至无法开始连接到您的网站,这意味着花费在对抗爬虫上的资源最少。当然可以在应用程序级别执行相同的操作 - 通过分析请求者的 IP 地址并提供错误、空回复或断开连接。但这意味着花费了太多资源(包括您编写逻辑的时间),而不是仅仅使用您的网络服务器的设施。而这种情况一般通过更换代理ip就可以解决掉,更换一个高匿名的代理ip,再次进入网站就不会被屏蔽掉了。2. 屏蔽更高级别的爬虫- 通过分析“用户代理”HTTP 标头,并提供一些 HTTP 错误,例如 503,而不是内容。您也可以直接断开连接,而不是在回复上花费资源。这意味着爬虫不会隐藏其身份,也不会使用某些Web浏览器的用户代理。这也意味着您在接受连接、分析请求和提供回复上花费了相当多的系统资源。一般不会将 robots.txt 称为阻止爬虫的方法,因为想阻止的大多数爬虫无论如何都不尊重 robots.txt。但是,如果您的问题是关于如何指示像 Googlebot 这样礼貌的抓取工具要抓取您网站的哪些部分,那么 robots.txt 是一种组织爬虫的选择。以上是“网站怎么阻止网络爬虫”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注辰迅云资讯频道!...

这篇文章将为大家详细讲解有关Python中虚拟环境virtualenv,pipreqs如何生成项目依赖第三方包,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。virtualenv简介含义:virtual:虚拟,env:environment环境的简写,所以virtualenv就是虚拟环境,顾名思义,就是虚拟出来的一个新环境,比如我们使用的虚拟机、docker,它们都是把一部分的内容独立出来,这部分独立的内容相当于一个容器,在这个容器只呢个,我们可以“为所欲为”----安装需要的依赖包,软件..,同时这个容器是与外界相互独立的,容器与容器直接也是互相独立不影响。为何要用虚拟环境:【前提概要】Django也是一个非常流行的web框架。由于Django的迭代更新非常快,也比较频繁,所以有一些过时的东西需要丢弃掉,一些新的东西需要加进来,从而导致不同的版本之间不兼容。比如Django1.3、Django1.4、Django1.8之间就有很大的差异性。或者是说,以Python的版本举例,现在工作中使用的Python版本与Python2.x和Python3.x两种。【故事背景】假设要进行Python web开发,使用的是Django。手上还有两个老项目A和B需要维护,而新项目C也正在开发中。这里项目A使用的是django1.3,项目B使用的是django1.4,而新项目C使用的是Django1.8。那么问题来了,如何同时在本地进行ABC这三个项目的开发和维护?正常的模式可能是这样:现在在A项目上有一个BUG需要修复,于是,先执行下面的命令,删除掉原来的版本:pip3 uninstall django 然后再执行下面的命令安装django1.3pip3 install django==1.3数分钟后,bug修复完毕,好,现在进行新项目C的开发了,然后又要重复上面的故事。好了,这还是最理想的情况。最不理想的情况就是基于django的第三方依赖也是跟Django版本相关的,于是除了install和uninstall Django之外,还要uninstall和install其依赖,Orz,这特么的就尴尬了...VirtualEnv能做什么呢?virtualenv可以搭建虚拟且独立的Python运行环境,使得单个项目的运行环境与其它项目独立起来。同时也可以用于在一台机器上创建多个独立的Python运行环境,VirtualEnvWrapper为前者提供了一些便利的命令行上的封装。virtualenv是一个非常不错的Python虚拟环境的创建工具,它最大的好处在于:可以让每个Python项目单独使用一个环境,而不会影响系统环境,也不会影响其它项目的环境。virtualenv可以用于创建独立的Python环境,在这些环境里面可以选择不同的Python版本或者不同的Packages,并且可以在没有root权限的情况下在环境里面重新安装新套件,互相不会产生任何影响,我们可以简单的认为虚拟环境就是一个沙箱系统,我们可以在里面“为所欲为 ”情况下还不会影响外面。virtualenv安装和使用virtualenv本质上是个python包, 使用pip安装:pip3 install virtualenv在工作目录下创建虚拟环境(默认在当前目录):注意需要自定义虚拟环境的名字!创建虚拟环境:cmd命令创建(创建目录为cmd命令当前目录,所以最好切换到所需要的目录下在进行创建)(1) virtualenv env_t1 (创建纯净环境)(2) virtualenv --system-site-packages env_t2 (创建环境,继承原安装的模块)创建虚拟环境有2中模式,一个是纯净模式,一个是基于系统环境的创建(自带了系统装的所有模块)-# 基于系统环境的创建模式,里面的模块其实是对系统的模块的一个引用,在虚拟环境中是卸载不掉的,因为它只是一种引用关系,除非系统卸载的模块,它才会没了。-# 纯净模式,里面的不包含系统的模块,需要自己下载安装,从头开始,所以这是在虚拟环境下安装的,你可以在后期卸载。一般来说,推荐使用纯净模式创建虚拟环境,这样根据自己的需求去安装第三方模块,同时如果想卸载的话也可以在虚拟环境中选择性的卸载。这样自由度更大,而不像另外一种模式,系统里有啥它都引用过来,而且还在虚拟环境中删除不了,影响加载速度等。使用pip3 list 来查看当前环境下安装的模块列表激活该虚拟环境:-windows进到目录里,的Script文件夹输入:activate-linux:soruse env1/Script/activate退出虚拟环境:-deactivate在pycharm中使用虚拟环境:-files--settings--Project--Project Interpreter--add选择虚拟环境路径下的python.exe即可三、pipreqs模块的介绍和使用当运行别人项目的时候,首先需要安装项目的依赖,不然就无法运行,Python的pipreqs模块就给我们提供了自动生成项目依赖内容的功能安装:pip3 install pipreqs使用:# 然后在项目所在的目录下使用命令生成包含依赖内容的文件pipreqs ./如果出现编码格式错误:UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 776: illegal multibyte sequence解决方法在命令后面指定编码格式:pipreqs ./ --encoding=utf8如果已经生成过一次依赖包文件requirements.txt,但是又项目新增了一下模块,此时再在后面添加--force覆盖参数重写即可pipreqs ./ --encoding='utf8' --force拿到依赖包文件我们可以快速自动下载依赖一键安装:pip3 install -r requirements.txttips:导出所有已安装的第三方模块:pip3 freeze > package.txt关于“Python中虚拟环境virtualenv,pipreqs如何生成项目依赖第三方包”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。...

Linux下怎么搭建NFS

2021/8/16 22:22:11

这篇文章主要讲解了“Linux下怎么搭建NFS”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux下怎么搭建NFS”吧!一、NFS简介NFS是Network File System的缩写,即网络文件系统。一种使用于分散式文件协定,有SUN公司开发。功能是通过网络让不同的机器、不同的操作系统能够分享个人数据,让应用程序通过网络可以访问位于服务器磁盘中的数据。NFS在文件传送或信息传送的过过程中,依赖于RPC协议。RPC,远程过程调用(Remote Procedure Call),是使客户端能够执行其他系统中程序的一种机制。NFS本身是没有提供信息传输的协议和功能的,但NFS却能让我们通过网络进行资料的分享,就是因为NFS使用了RPC提供的传输协议,可以说NFS就是使用PRC的一个程序。环境说明:系统 :CentOS release 6.7 (Final)NFS IP :10.219.24.22web IP :10.219.24.25iptables:未运行防火墙操作流程:1、软件安装,NFS只需要安装两个软件,在通常情况下是作为系统默认软件安装的[root@mysql01 ~]# rpm -qa|grep rpcbind*rpcbind-0.2.0-11.el6.x86_64[root@mysql01 ~]# rpm -qa|grep nfs-utilsnfs-utils-1.2.3-64.el6.x86_64nfs-utils-lib-1.1.5-11.el6.x86_64说明:[root@mysql01 ~]# yum install rpcbind nfs-utils (如果没有安装就yum安装)rpcbind包 :centos 下面RPC主程序nfs-utils包 :NFS服务主程序,包括NFS的基本命令和监控程序2、开启RCP服务[root@mysql01 ~]# /etc/init.d/rpcbind start查看rpcbind服务端口 [root@mysql01 ~]# netstat -antlp|grep rpcbindtcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1462/rpcbind tcp 0 0 :::111 :::* LISTEN 1462/rpcbind [root@mysql01 ~]# rpcinfo -p localhostprogram vers proto port service100000 4 tcp 111 portmapper100000 3 tcp 111 portmapper100000 2 tcp 111 portmapper100000 4 udp 111 portmapper100000 3 udp 111 portmapper100000 2 udp 111 portmapper100024 1 udp 41757 status100024 1 tcp 42661 status3、开启NFS服务[root@mysql01 ~]# /etc/init.d/nfs start Starting NFS services: [ OK ]Starting NFS quotas: [ OK ]Starting NFS mountd: [ OK ]Starting NFS daemon: [ OK ]Starting RPC idmapd: [ OK ][root@mysql01 ~]# rpcinfo -p localhostprogram vers proto port service......100005 3 tcp 59454 mountd100003 2 tcp 2049 nfs100003 3 tcp 2049 nfs100003 4 tcp 2049 nfs100227 2 tcp 2049 nfs_acl100227 3 tcp 2049 nfs_acl100003 2 udp 2049 nfs100003 3 udp 2049 nfs100003 4 udp 2049 nfs100227 2 udp 2049 nfs_acl100227 3 udp 2049 nfs_acl....100021 4 tcp 42905 nlockmgr说明: rpc上应该能看到好多新被注册的nfs端口两个服务开机自启动[root@mysql01 ~]# chkconfig rpcbind on[root@mysql01 ~]# chkconfig nfs on4、服务端配置共享目录(/oradata)4.1 配置前确认rpcbind、nfs服务进程正常[root@nfs01 ~]# /etc/init.d/nfs status[root@nfs01 ~]# /etc/init.d/rpcbind status[root@nfs01 ~]# ps -ef|egrep "rpc|nfs"4.2 创建共享目录并授权("nfsnobody")#nfsnobody 用户是开启rpc、nfs进程后系统自动创建的[root@mysql01 ~]# df -hFilesystem Size Used Avail Use% Mounted on/dev/sda3 35G 8.9G 25G 27% /tmpfs 491M 76K 491M 1% /dev/shm/dev/sda1 2.9G 4.5M 2.7G 1% /tmp/dev/sr0 3.7G 3.7G 0 100% /media/CentOS_6.7_Final[root@mysql01 ~]# mkdir /oradata[root@mysql01 ~]# chown -R nfsnobody.nfsnobody /oradata [root@mysql01 ~]# chmod 777 /oradata4.3 修改服务端配置文件(/etc/exports)[root@mysql01 ~]# cat /etc/exports #share /data by andy for XXXX at 20170812/oradata 10.219.24.0/8(rw,sync)[root@mysql01 ~]#4.3 查看系统加载的配置[root@mysql01 ~]# cat /var/lib/nfs/etab /oradata 10.219.24.0/8(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534,sec=sys,rw,root_squash,no_all_squash)4.4 重新平滑加载服务[root@mysql01 ~]# showmount -e localhost5、客户端配置[root@mysql02 ~]# /etc/init.d/rpcbind statusrpcbind (pid 1469) is running...[root@mysql02 ~]# /etc/init.d/rpcbind start挂载nfs共享目录[root@mysql02 ~]# mount -t nfs 10.219.24.22:/oradata /mnt[root@mysql02 ~]# df -hFilesystem Size Used Avail Use% Mounted on/dev/sda3 35G 8.7G 25G 26% /tmpfs 491M 76K 491M 1% /dev/shm/dev/sda1 2.9G 4.5M 2.7G 1% /tmp/dev/sr0 3.7G 3.7G 0 100% /media/CentOS_6.7_Final10.219.24.22:/oradata35G 8.9G 25G 27% /mnt6、开机自动挂载方法一:[root@mysql02 ~]# echo "mount -t nfs 10.219.24.22:/oradata /mnt">>/etc/rc.local方法二:开启netfs服务[root@mysql02 ~]# chkconfig netfs on[root@mysql02 ~]# vi /etc/fstab[root@mysql02 ~]# cat /etc/fstab10.219.24.22:/oradata /mnt nfs defaults 0 07、检验-- nfs server[root@mysql01 ~]# touch /oradata/aa-- client[root@mysql02 ~]# cd /mnt[root@mysql02 mnt]# lltotal 0-rw-r--r--. 1 root root 0 Aug 13 04:31 aa感谢各位的阅读,以上就是“Linux下怎么搭建NFS”的内容了,经过本文的学习后,相信大家对Linux下怎么搭建NFS这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是辰迅云,小编将为大家推送更多相关知识点的文章,欢迎关注!...