首页 文章 精选 留言 我的

精选列表

搜索[快速入门],共10000篇文章
优秀的个人博客,低调大师

Java动态代理之InvocationHandler最简单的入门教程

网上关于Java的动态代理,Proxy和InvocationHandler这些概念有讲解得非常高深的文章。其实这些概念没有那么复杂。现在咱们通过一个最简单的例子认识什么是InvocationHandler。值得一提的是,InvocationHandler在Spring框架实现中被广泛使用,这意味着我们吃透了InvocationHandler,就为将来的Spring源码学习打下一个坚实的基础。 开发一个接口,包含两个方法,可以向指定的人问候“你好”或者“再见”。 public interface IHello { void sayHello(String name); void sayGoogBye(String name); } 创建一个简单的类,实现这个IHello接口。 public class Helloimplements implements IHello { @Override public void sayHello(String name) { System.out.println("Hello " + name); } @Override public void sayGoogBye(String name) { System.out.println(name+" GoodBye!"); } } 消费这个实现类,迄今为止没什么特别的。 现在假设我们接到了这个需求:老板要求在该实现类每次问候某人时,必须把问候的细节记录到日志文件里。为了简单起见,我们在问候前打印下面的一行语句来模拟日志记录的动作。 System.out.println("问候之前的日志记录..."); 您也许会说,这还不简单?直接修改Helloimplements的对应方法,把这行日志插入到对应方法即可。 然而,老板的要求是:不允许你修改原来的Helloimplements类。在现实场景中,Helloimplements可能是第三方的jar包提供的,我们没有办法修改代码。 您也许会说,我们可以用设计模式里的代理模式,即创建一个新的Java类作为代理类,同样实现IHello接口,然后将Helloimplements类的实例传入代理类。我们虽然被要求不允许修改Helloimplements的代码,但是可以把日志记录代码写在代理类里。完整代码如下: public class StaticProxy implements IHello { private IHello iHello; public void setImpl(IHello impl){ this.iHello = impl; } @Override public void sayHello(String name) { System.out.println("问候之前的日志记录..."); iHello.sayHello(name); } @Override public void sayGoogBye(String name) { System.out.println("问候之前的日志记录..."); iHello.sayGoogBye(name); } static public void main(String[] arg) { Helloimplements hello = new Helloimplements(); StaticProxy proxy = new StaticProxy(); proxy.setImpl(hello); proxy.sayHello("Jerry"); } } 这种做法能够实现需求: 下面我们再看如何用InvocationHandler实现同样的效果。 InvocationHandler是一个JDK提供的标准接口。看下面的代码: import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynaProxyHello implements InvocationHandler { private Object delegate; public Object bind(Object delegate) { this.delegate = delegate; return Proxy.newProxyInstance( this.delegate.getClass().getClassLoader(), this.delegate .getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; try { System.out.println("问候之前的日志记录..."); // JVM通过这条语句执行原来的方法(反射机制) result = method.invoke(this.delegate, args); } catch (Exception e) { e.printStackTrace(); } return result; } 上面代码里的bind方法很想我之前代理类StaticProxy的setImpl方法,只不过这个bind方法的输入参数类型更加通用。日志记录的代码写在方法invoke里。 看看如何使用: static public void main(String[] arg) { DynaProxyHello helloproxy = new DynaProxyHello(); Helloimplements hello = new Helloimplements(); IHello ihello = (IHello) helloproxy.bind(hello); ihello.sayHello("Jerry"); } 执行效果和StaticProxy那种解决方案完全一致。 咱们先来调试一下。当bind方法执行时,方法Proxy.newProxyInstance被调用,Helloimplements类的实例被传入。 我们在调试器里观察IHello ihello = (IHello) helloproxy.bind(hello)这行语句返回的ihello变量。虽然它的静态类型是IHello,但请注意,在调试器里观察它的实际类型,并不是Helloimplements的实例,而是JVM给我们加过工的,包含了我们在invoke方法里手写的那行日志记录代码。这个ihello类型为$Proxy0。 当这个被JVM加过工的变量的sayHello方法被调用时,JVM自动将调用转交到DynaProxyHello.invoke去: 于是,在invoke方法里,我们手写的日志记录代码被执行,然后通过Java反射执行原始的sayHello代码。 有的朋友可能会问,你这个InvocationHandler看起来比静态代理StaticProxy还复杂啊?有什么好处? 假设老板的需求又变了,在调用问候和说再见的方法里,要使用不同的日志记录策略。 看看用InvocationHandler如何优雅实现吧: 希望这个例子能让大家对Java的动态代理之InvocationHandler有了最基本的了解。要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:

优秀的个人博客,低调大师

Spring Boot入门(12)实现页面访问量统计功能

在日常的网站使用中,经常会碰到页面的访问量(或者访问者人数)统计。那么,在Spring Boot中该如何实现这个功能呢? 我们的想法是比较简单的,那就是将访问量储存在某个地方,要用的时候取出来即可,储存的位置可选择数据库或者其他文件。本例所使用的例子为txt文件,我们将访问量数据记录在D盘的count.txt文件中。 下面直接开始本次的项目。整个项目的完整结构如下: 我们只需要修改划红线的三个文件,其中build.gradle的代码如下: buildscript { ext { springBootVersion = '2.0.3.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile('org.springframework.boot:spring-boot-starter-web') // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf', version: '2.0.1.RELEASE' } 视图文件(模板)index.HTML的代码如下: <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>访问统计</title> <script th:inline="javascript"> function load(){ var count = [[${count}]]; document.getElementById("visit").innerHTML = count.toString(); } </script> </head> <body onload="load()"> <h1>Hello, world!</h1> <p>&emsp;&emsp;本页面已被访问<span id="visit"></span>次。</p> </body> </html> 控制器文件VisitController.java文件的代码如下: package com.example.visit.Controller; import java.io.*; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class VisitController { @GetMapping("/index") public String Index(Map <String, Object> map){ // 获取访问量信息 String txtFilePath = "D://count.txt"; Long count = Get_Visit_Count(txtFilePath); System.out.println(count); map.put("count", count); // 后台参数传递给前端 return "index"; } /* * 获取txt文件中的数字,即之前的访问量 * 传入参数为: 字符串: txtFilePath,文件的绝对路径 */ public static Long Get_Visit_Count(String txtFilePath) { try { //读取文件(字符流) BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(txtFilePath),"UTF-8")); //循环读取数据 String str = null; StringBuffer content = new StringBuffer(); while ((str = in.readLine()) != null) { content.append(str); } //关闭流 in.close(); //System.out.println(content); // 解析获取的数据 Long count = Long.valueOf(content.toString()); count ++; // 访问量加1 //写入相应的文件 BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(txtFilePath),"UTF-8")); out.write(String.valueOf(count)); //清楚缓存 out.flush(); //关闭流 out.close(); return count; } catch (Exception e){ e.printStackTrace(); return 0L; } } } 这样我们就完成了整个项目的配置,最后,我们在D盘中的count.txt中写入数字0,作为初始访问量。 运行Spring Boot项目,在浏览器中输入localhost:8080/index , 显示的页面如下: 刚载入页面时,显示页面被访问1次。当我们将这个这也载入10次后,显示如下: 这样我们就用Spring Boot实现了页面访问量的统计功能。 本次分享到此结束,欢迎大家交流~~ 注意:本人现已开通两个微信公众号: 因为Python(微信号为:python_math)以及轻松学会Python爬虫(微信号为:easy_web_scrape), 欢迎大家关注哦~~

优秀的个人博客,低调大师

【Java入门提高篇】Day17 Java异常处理(下)

今天继续讲解java中的异常处理机制,主要介绍Exception家族的主要成员,自定义异常,以及异常处理的正确姿势。 Exception家族 一图胜千言,先来看一张图。 Exception这是一个父类,它有两个儿子,IOException和RuntimeException,每个儿子都很能生,所以它有着一堆的孙子,但其实,Exception家族还有一个大家伙,那就是Throwable,这是一个接口,看名字就知道意思,就是“可被抛出”嘛,它还有一个同父异母的哥哥,那就是Error,这家伙可厉害了,Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢出等。catch语句里,不仅可以catch住Exception,还能catch住Error(什么?你真的打算catchError??程独秀同学,你先坐下。)一般情况下,是不能捕获Error的,对于这类错误,Java编译器不去检查他们。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和预防,遇到这样的错误,建议让程序终止。除非你有把握能正确处理,否则程独秀同学还是坐下吧(滑稽)。 UncheckedException和CheckedException 你也许会一脸懵逼,???,这是啥?异常也是分派别的,Unchecked Exception表示“未检查异常“,CheckedException自然就是”已检查异常“,派生于Error或者RuntimeException的异常称为unchecked异常,所有其他的异常成为checked异常。那问题来了,为啥要区分这两种异常? 我们可以再看看上面那个图,可以看出,RuntimeException和Error都是由程序内部引发的错误,比如上一篇里所说的空指针和算术异常。而CheckedException则大都是由外部因素导致的,如文件无法找到异常,这是虚拟机无法掌控的情况,当出现异常,虚拟机也只能一脸懵逼,不知道该如何是好,所以当有可能发生时,就必须要使用try..catch去捕获它,而对于Unchecked Exception时,大部分是由于代码引发的,所以只要代码写的足够完善,是不会抛出这样的异常的,所以也不强制要求捕获。 所以原因其实很简单,编译器将检查你是否为所有的已检查异常提供了异常处理机制,比如说我们使用Class.forName()来查找给定的字符串的class对象的时候,如果没有为这个方法提供异常处理,编译是无法通过的。已检查异常的意义就在于让你知道,这地方是有可能抛异常的,你要注意了,赶紧捕获了。 自定义异常 那么如何自定义一个异常呢?其实很简单,只需要继承Exception类就好了。看下面的栗子: public class MyException extends Exception { public MyException() { super(); } public MyException(String message) { super(message); } public MyException(String message, Throwable cause) { super(message, cause); } public MyException(Throwable cause) { super(cause); } protected MyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } } MyException继承了Exception类,重写了构造函数,并没有加自己的逻辑,只是调用了父类的方法。你看,自定义一个异常其实很简单吧。看到这你也许又疑惑了,这尼玛好像就是给Exception换了个名字,有啥用??? 别急,别急,你忘了吗,Exception不仅是可以捕获的,还是可以主动抛出的,所以当遇到某些特定的情况时,我们就可以主动抛出异常,然后在调用时去捕获它,获取异常信息,如果直接用Exception的话,那么捕获的时候,会把所有的异常,该捕获不该捕获的都一起捕获了,那么就没法区分哪些是我们主动抛出来的异常了,这样就无法对那些异常进行特殊处理了。 异常处理的正确姿势 接下来要简单介绍一个实际使用中常用的异常处理方法——异常链化处理。 在一些大型的,模块化的软件开发中,一旦一个地方发生异常,则如骨牌效应一样,将导致出现一连串的异常。假设B模块需要调用A模块的方法,如果A模块发生异常,则B也将不能完成而发生异常,但是B在抛出异常时,会将A的异常信息掩盖掉,这将使得异常的根源信息丢失。而使用异常的链化可以将多个模块的异常串联起来,使得异常信息不会丢失。 异常链化就是用一个异常对象为参数构造新的异常对象。新的异对象将包含先前异常的信息。这项技术主要是异常类的一个带Throwable参数的函数来实现的。这个当做参数的异常,我们叫他根源异常(cause)。如果你细心一点的话,会发现上面的栗子里也有一个叫做cause的东西,没错,说的其实就是它,在new一个新的异常时,将之前的异常信息传入构造函数即可。下面再用一个简单的栗子进行说明: public class Test { public static void main(String[] args) { System.out.println("请输入2个加数"); int result; try { result = add(); System.out.println("结果:"+result); } catch (Exception e){ e.printStackTrace(); } } /** * 执行加法计算 */ private static int add() throws Exception { int result; try { List<Integer> nums =getInputNumbers(); result = nums.get(0) + nums.get(1); }catch(InputMismatchException immExp){ //链化:以一个异常对象为参数构造新的异常对象。 throw new Exception("计算失败",immExp); } return result; } /** * 获取输入的整数 */ private static List<Integer> getInputNumbers() { List<Integer> nums = new ArrayList<>(); Scanner scan = new Scanner(System.in); try { int num1 = scan.nextInt(); int num2 = scan.nextInt(); nums.add(new Integer(num1)); nums.add(new Integer(num2)); }catch(InputMismatchException immExp){ throw immExp; }finally { scan.close(); } return nums; } } 输出如下: 请输入2个加数 d d java.lang.Exception: 计算失败 at com.frank.chapter17.Test.add(Test.java:35) at com.frank.chapter17.Test.main(Test.java:18) Caused by: java.util.InputMismatchException at java.util.Scanner.throwFor(Scanner.java:864) at java.util.Scanner.next(Scanner.java:1485) at java.util.Scanner.nextInt(Scanner.java:2117) at java.util.Scanner.nextInt(Scanner.java:2076) at com.frank.chapter17.Test.getInputNumbers(Test.java:47) at com.frank.chapter17.Test.add(Test.java:31) ... 1 more 可以看到,当输入的不是整数时,发生了异常,在getInputNumbers方法里没有处理这个异常,而是将它继续抛出,在add方法里捕获了异常之后,以该异常为构造参数,重新抛出了一个异常,从打印输出的信息可以看到,不仅仅有第二次抛出的异常信息,第一次的输出信息不匹配异常的详细信息也包含在了里面,衔接在Causedby之后,形成了一条异常链,这样可以方便我们更快的排查问题所在。 至此,异常就讲解完毕了,希望能给大家带来一些启发和思考,如果觉得还算ok的话,记得动动小手点推荐,让更多人可以看到,也欢迎关注我的博客,会持续更新的。如果有什么讲的不好的地方。。。emmmmmm,你倒是来打我呀(逃) 真正重要的东西,用眼睛是看不见的。

优秀的个人博客,低调大师

【Java入门提高篇】Day16 Java异常处理(上)

当当当当当当,各位看官,好久不见,甚是想念。 今天我们来聊聊Java里的一个小妖精,那就是异常。 什么是异常?什么是异常处理? 异常嘛,顾名思义就是不正常,(逃),是Java程序运行时,发生的预料之外的事情,它阻止了程序按照程序员的预期正常执行。 异常处理,应该说异常处理机制,就是专门用来制服这个小妖精的法宝。Java中的异常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰。 简而言之,Java异常处理就是能让我们主动迎击可能到来的异常,并将它们以圆润的方式处理掉。 还是先来看个小栗子,看看java里的异常长什么样。 public class Test { public static void main(String args[]){ int i = 0 / 0; System.out.println("i = " + i); } } 别慌别慌,不要看到红色提示就内心崩溃只想关掉IDE,来,抓紧我的手,带你看清“异常”这个磨人的小妖精的真面目(滑稽)。 代码里将0作为了分母,因此程序会发生算术异常,抛出一个异常后,如果没有任何处理,默认会终止程序,所以后面的打印内容并没有输出。在异常内容里,有说明异常类型为:java.lang.ArithmeticException,也就是算术异常,后面跟着的是异常原因: / by zero,也就是说异常出现的原因是将0作为了分母,而且后面还有堆栈信息,指出了异常抛出的位置是在com.frank.chapter16.main.Test.main这个包下,Test类的第11行(这个行数如果跟你想的不一样,不要在意,因为我的代码开始之前还有一些不可描述的说明信息),因为只有一次方法调用,所以没有很长的堆栈信息,看起来也很简洁明了。 所以你看,其实异常也没那么可怕吧,不仅给了异常原因,还告诉了你这个bug是出在第几行,所以好好利用它,可以帮助你写出更难以发现的bug,呸,说错了,可以帮助你更容易找到bug(手动滑稽)。 如果不希望抛出异常后程序就结束,而是希望它继续运行呢?那么就捕获它。 如何使用异常处理 我们来把上面那个栗子改改: public class Test { public static void main(String args[]){ try{ int i = 0 / 0; }catch (Exception e){ System.out.println("好像发生异常了,但是我不管,我还要继续运行"); } System.out.println("运行完毕!"); } } 输出如下: 好像发生异常了,但是我不管,我还要继续运行 运行完毕! 好的,很强势,现在即使抛出了异常,程序也继续运行了。异常就像是一头野兽,但你一旦捕获它,驯服它,就可以为你所用,为所欲为了。 try...catch...是常用的异常处理搭配,如果在try语句块中发生了异常,如果刚好这个异常被捕获到了,那么会直接跳到catch语句块中,执行catch语句中的代码,像上面的栗子里,因为对Exception类进行了捕获处理,所以当它的子类异常java.lang.ArithmeticException被抛出来的时候,也能捕获它。关于Exception类的结构层次关系,后面再做详细介绍。 还有另外一种搭配方式,那就是try...catch...finally,finally语句块比catch要强势的多,前面说了catch语句块必须要捕获到了特定的Exception才会执行里面的代码,如果catch的是ArithmeticException但是抛出的却是空指针异常,那就不会被捕获了,异常也就逃之夭夭了。这个时候,finally的优势就展示出来了,不管抛出什么样的异常,也不管是否抛出了异常,finally中的代码都会被执行。所以一般的用法是在finally语句块里释放掉那些需要被释放的资源,如socket连接,关闭io流,关闭数据库连接等等。也就是说一般在finally中收拾try中抛出的烂摊子,心疼一秒finally,果然能者多劳啊。 当然,try...finally这样的搭配也是ok的,需要注意的是,当try语句中发生了异常之后,在发生异常处之后的代码将不会再执行,而是跳到相应的catchu或者finally中去。 public class Test { public static void main(String args[]){ try{ int i = 0 / 0; }catch (NullPointerException e) { System.out.println("这里捕获空指针异常"); }catch (ArithmeticException e){ System.out.println("这里捕获算术异常"); }finally { System.out.println("这里是finally"); } System.out.println("运行完毕!"); } } 输出如下: 这里捕获算术异常 这里是finally 运行完毕! 在上面的代码中,catch语句块是可以同时使用多个的,第一个catch语句块捕获的是空指针异常,但由于抛出的是算术异常,所以没有捕获住,但被第二个catch捕获到了,所以第二个catch语句块中的代码执行了。异常匹配是按照从上到下的顺序进行匹配的,最后才执行finally中的代码块。关于try...catch...finally,还有一个很有趣的return问题,如果三个语句块里都有return,最终返回结果会是怎样呢?这里做了详细的说明,http://www.cnblogs.com/mfrank/p/7895660.html 有兴趣的话可以看一看。 绝大多数情况下,finally中的代码都是会被执行的,只有一种情况下,finally中的代码不会被执行,那就是在try语句块中结束掉了虚拟机(如:使用 System.exit(0); )。 关于异常,还有一个关键字需要介绍,那就是throw,使用throw可以主动抛出一个异常。看到这你也许会一脸懵逼,主动抛出???嫌异常不够多,凑热闹不嫌事大??别急别急,中间一定有什么误会,把刀放下,有话好好说。 throw关键字确实是用来抛出异常的,你可以这样使用: public class Test { public static void main(String args[]){ try{ throw new NullPointerException("听说你很闲,给你抛个异常。"); }catch (NullPointerException e) { System.out.println("这里捕获空指针异常,提示内容:" + e.getMessage()); e.printStackTrace(); } } } 输出如下: 这里捕获空指针异常,提示内容:听说你很闲,给你抛个异常。 java.lang.NullPointerException: 听说你很闲,给你抛个异常。 at com.frank.chapter16.main.Test.main(Test.java:11) 用throw关键字可以抛出任意类型的异常,当然,你想的话,还有抛Error,至于什么是Error,已经跟Exception的关系,将在下一篇里进行讲解。暂时不用深究。 在throw异常的时候,可以加上抛出异常的原因,这样可以更方便定位问题所在,当然,一般来说不会像栗子中这样使用的,这里只是为了简单起见。 到此为止,异常的上半篇已经讲解完毕,在这一篇里,说明了什么是异常,什么是异常处理,以及如何使用异常处理机制。相信大家对这个小妖精有了初步的认识,下一篇中,将会讲解Exception家族都有哪些成员,如何使用自定义异常,已经异常处理的实际使用中的正确姿势。欢迎大家继续关注,之后计划每周两篇以上的更新,如果有讲解遗漏或者不好的地方,欢迎大家及时指出,共同进步! 真正重要的东西,用眼睛是看不见的。

优秀的个人博客,低调大师

入门必备】史上最全的深度学习资源汇总,速藏!

目录: 介绍 教程视频数据集项目论文 介绍: 作为传统机器学习重要的一个分支,与机器学习算法相比,深度学习算法最大的特点是至少含有一个隐藏层的神经网络(NN)。此外,深度学习的分层处理的思想也大大提高了模型的泛化能力。深度学习发展到今天,大致分为以下一些比较流行的网络结构:深度神经网络(DNN)、卷积神经网络(CNN)、循环神经网络(RNN)、生成对抗网络(GAN)等。应用最广的几个研究领域分别是自然语言处理、语音识别和图像处理。出现了Tensorflow、Keras、Caffe、Torch等技术框架。深度学习近年来发展迅猛,在国内外都引起了广泛的关注,也吸引了越来越多的人投身于深度学习领域的研究。今天小编有幸为大家介绍一些我自认为不错的深度学习资源,希望帮助热爱深度学习的小伙伴能够走的更远。 教程: Topal的深度学习教程,从感

优秀的个人博客,低调大师

带你入门Python数据挖掘与机器学习(附代码、实例)

一、数据挖掘与机器学习技术简介 什么是数据挖掘?数据挖掘指的是对现有的一些数据进行相应的处理和分析,最终得到数据与数据之间深层次关系的一种技术。例如在对超市货品进行摆放时,牛奶到底是和面包摆放在一起销量更高,还是和其他商品摆在一起销量更高。数据挖掘技术就可以用于解决这类问题。具体来说,超市的货品摆放问题可以划分为关联分析类场景。 在日常生活中,数据挖掘技术应用的非常广泛。例如对于商户而言,常常需要对其客户的等级(svip、vip、普通客户等)进行划分,这时候可以将一部分客户数据作为训练数据,另一部分客户数据作为测试数据。然后将训练数据输入到模型中进行训练,在训练完成后,输入另一部分数据进行测试,最终实现客户等级的自动划分。其他类似的应用例子还有验证码识别、水果品质自动筛选等。 那么机器学习技术又是什么呢?一言以蔽之,凡是让机器通过我们所

优秀的个人博客,低调大师

Python入门(二)快捷键、操作符和BIF

快捷键(常用) 新建文件:Ctrl+N; 打开文件:Ctrl+O; 打开模块:Alt+M(先选中模块,再按下此快捷键,会打开该模块的python源码); 浏览模块:Alt+C; 路径浏览: Alt+FP; 光标当前所在行列:IDLE右下角有显示; 跳到目标行号:Alt+G; 调出上一条命令:Alt+P; 调出下一条命令: Alt+N; 跳到开头:Ctrl+uparrow; 跳到结尾:Ctrl+downarrow; 跳到上一行开头:Ctrl+leftarrow; 跳到下一行开头:Ctrl+rightarrow; 全选:Ctrl+A; 缩进代码:Tab/空格(注意:这两种方式缩进量可能不同,会导致运行时会报错“unexpected indent”,所以,编程时最好只采取一种;如果已经混用,可以在编程结束后,先Ctrl+A、再Alt+5/6、再OK,三步即可解决); 补齐文中出现过的单词:Alt+/; 查找:Ctrl+F; 再次查找:Ctrl+G; 查找选中部分:Ctrl+F3; 查找文件:Alt+F3; 替换:Ctrl+H; 撤销:Ctrl+Z; 反撤销:Ctrl+Shift+Z; 注释代码行:Alt+3; 取消注释代码行:Alt+4; 全选:Ctrl+A; 运行代码:F5; 保存代码:Ctrl+S; 另存为:Ctrl+Shift+S; 保存副本:Alt+Shift+S; 打印窗口:Ctrl+P; 关闭:Alt+F4; 退出:Ctrl+Q; 打开Python文件:F1; 单步调试:Alt+DD; 定位到错误位置:Alt+DG(先定位到错误行,再按下此快捷键); 显示错误历史:Alt+DA; 重新启动shell:Ctrl+F6 。 操作符 按优先级由高到底排列: 幂运算[**]; 正负号[+ -]; 算数操作符[* / // % + -]; 比较操作符[< <= > >= == != <>]; 逻辑运算符 not and or 。 注:编程时适当使用(),可增加程序的可读性。 BIF Built-in functions的缩写,意为内置函数,编程时通过使用内置函数实现各种功能。本文不具体分析每个BIF的具体使用,只说明查找BIF功能的方法,具体使用会在以后的文章中结合实例分析。 在IDLE中输入: dir(__builtins__) 显示如下列表,其中全都为小写的字符串为BIF。 如果想知道某个BIF的功能,直接在IDLE内查找即可(这里以super()函数为例),输入以下代码: help(super) super()函数的功能及使用方法显示如下: 如果有些英文看不懂,可以借助翻译软件。 有了以上了解,不禁发现Python和MATLAB有很多相似之处,这里借助奥特曼超人很久之前的一段话,浅略地对两者进行比较: 国外近几年比较流行的是MATLAB,但它是商用,和Oracle一样,需要付费,且价格不菲。如果使用Python做科学计算,一方面完全免费,同时众多开源的科学计算库都提供了Python的调用接口,用户可以在任何计算机上免费安装Python及其绝大多数的扩展库;其次Python是一门更易学、更严谨的程序设计语言,它能让用户编写出更易读、易维护的代码;最后Python有着丰富的扩展库,可以轻易完成各种高级任务,开发者可以用Python实现完整应用程序所需的各种功能。 END!

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册