首页 文章 精选 留言 我的

精选列表

搜索[博客系统],共10000篇文章
优秀的个人博客,低调大师

[雪峰磁针石博客]大数据Hadoop工具python教程3-MapReduce

MapReduce是一种编程模型,通过将工作分成独立的任务并在一组机器上并行执行任务,可以处理和生成大量数据。 MapReduce编程风格的灵感来自函数式编程结构map和reduce,它们通常用于处理数据列表。在高层MapReduce程序将输入数据元素列表转换为输出数据元素列表两次,一次在映射阶段,一次在还原阶段。 本章首先介绍MapReduce编程模型,并描述数据如何流经模型的不同阶段。然后示例如何使用Python编写MapReduce作业。 数据流 MapReduce框架由三个主要阶段组成:map,shuffle和sort,以及reduce。 map 在映射阶段,mapper函数处理一系列键值对。映射器按顺序处理键值对,产生零个或多个输出键值对。 比如将句子转换为单词。输入是包含句子的字符串,映射器将句子拆分为单词并输出单词。 Shuffle和Sort 映射阶段的中间输出将移动到reducer。将输出从映射器移动到reducer的过程称为洗(shuffling)。 Shuffling由分区函数处理,称为partitioner。partitioner用于控制从映射器到reducer的键值对的流动。reducer知道映射器的输出键和reducer的数量,返回预期的reducer的索引。partitioner程序确保将同一键的所有值发送到同一reducer。默认分区程序是基于哈希的。它计算映射器输出键的哈希值,并根据此结果分配分区。 reducers开始处理数据之前的最后阶段是排序过程。在呈现给reducer之前,每个分区的中间键和值都由Hadoop框架排序。 Reduce 在reducer阶段,值的迭代器被提供给称为reducer的函数。迭代器把值提供给reducer,这些值是唯一键的一组非唯一值。 reducer聚合每个唯一键的值,并产生零个或多个输出键值对。数据流| 比如对键的所有值求和。此reducer的输入是键的所有值,reducer对所有值求和。然后,reducer输出键值对中包含输入键和输入键值的总和。 参考资料 python测试开发项目实战-目录 python工具书籍下载-持续更新 python 3.7极速入门教程 - 目录 原文地址 本文涉及的python测试开发库 谢谢点赞! [本文相关海量书籍下载](https://github.com/china-testing/python-api-tesing/blob/master/books.md Hadoop流 Hadoop流是与Hadoop发行版一起打包的工具,它允许使用任何可执行文件创建MapReduce作业作为映射器和reducer。 Hadoop流实用程序支持Python,shell。 mapper和reducer都是可执行文件,它们从标准输入(stdin),逐行读取输入,并将写入标准输出(stdout)。 Hadoop流公国创建MapReduce作业,将作业提交到集群,并监视其进度直到完成。 mapper初始化时,每个映射任务都会将指定的可执行文件作为单独的进程启动。映射器读取输入文件,并通过stdin将每行显示给可执行文件。在可执行文件处理每行输入后,映射器从stdout收集输出并将每一行转换为键值对。键由第一个制表符前面的行部分组成,值由第一个制表符后面的行部分组成。如果一行不包含制表符,则整行被视为键,值为null。 初始化reducer时,每个reduce任务都会将指定的可执行文件作为单独的进程启动。 reducer将输入键值对转换为通过stdin呈现给可执行文件的行。 reducer从stdout收集可执行文件的结果,并将每一行转换为键值对。与映射器类似,可执行文件通过制表符分隔键和值来指定键值对。 下面我们用python来模拟Hadoop流工具。 mapper.py:在WordCount的map阶段实现逻辑的Python程序。它从stdin读取数据,将行拆分为单词,并将每个单词的中间计数输出到stdout。 #!/usr/bin/env python # https://github.com/china-testing/python-api-tesing import sys # Read each line from STDIN for line in sys.stdin: # Get the words in each line words = line.split() # Generate the count for each word for word in words: # Write the key-value pair to STDOUT to be processed by the reducer. # The key is anything before the first tab character and the value is # anything after the first tab character. print('{0}\t{1}'.format(word, 1)) reducer.py是在WordCount的reduce阶段实现逻辑的Python程序。它从stdin中读取mapper.py的结果,对每个单词的出现次数求和,并将结果写入stdout。 #!/usr/bin/env python import sys curr_word = None curr_count = 0 # Process each key-value pair from the mapper for line in sys.stdin: # Get the key and value from the current line word, count = line.split('\t') # Convert the count to an int count = int(count) # If the current word is the same as the previous word, increment its # count, otherwise print the words count to STDOUT if word == curr_word: curr_count += count else: # Write word and its number of occurrences as a key-value pair to STDOUT if curr_word: print('{0}\t{1}'.format(curr_word, curr_count)) curr_word = word curr_count = count # Output the count for the last word if curr_word == word: print('{0}\t{1}'.format(curr_word, curr_count)) 执行 $ echo 'jack be nimble jack be quick' | ./mapper.py | sort -t 1 | ./reducer.py be 2 jack 2 nimble 1 quick 1 现在我们把'jack be nimble jack be quick'存成/home/hduser_/input2.txt,用hadoop来实现这一过程。 $ hdfs dfs -put /home/hduser_/input2.txt /user/hduser $ $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-2.9.2.jar -files mapper.py,reducer.py -mapper mapper.py -reducer reducer.py -input /user/hduser/input2.txt -output /user/hduser/output 19/01/22 10:44:38 INFO Configuration.deprecation: session.id is deprecated. Instead, use dfs.metrics.session-id 19/01/22 10:44:38 INFO jvm.JvmMetrics: Initializing JVM Metrics with processName=JobTracker, sessionId= 19/01/22 10:44:38 INFO jvm.JvmMetrics: Cannot initialize JVM Metrics with processName=JobTracker, sessionId= - already initialized 19/01/22 10:44:38 ERROR streaming.StreamJob: Error Launching job : Output directory hdfs://localhost:54310/user/hduser/output already exists Streaming Command Failed! hduser_@andrew-PC:/home/andrew/code/HadoopWithPython/python/MapReduce/HadoopStreaming$ $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-2.9.2.jar -files mapper.py,reducer.py -mapper mapper.py -reducer reducer.py -input /user/hduser/input2.txt -output /user/hduser/output2 19/01/22 10:44:45 INFO Configuration.deprecation: session.id is deprecated. Instead, use dfs.metrics.session-id 19/01/22 10:44:45 INFO jvm.JvmMetrics: Initializing JVM Metrics with processName=JobTracker, sessionId= 19/01/22 10:44:45 INFO jvm.JvmMetrics: Cannot initialize JVM Metrics with processName=JobTracker, sessionId= - already initialized 19/01/22 10:44:46 INFO mapred.FileInputFormat: Total input files to process : 1 19/01/22 10:44:46 INFO mapreduce.JobSubmitter: number of splits:1 19/01/22 10:44:46 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_local208759810_0001 19/01/22 10:44:46 INFO mapred.LocalDistributedCacheManager: Localized file:/home/andrew/code/HadoopWithPython/python/MapReduce/HadoopStreaming/mapper.py as file:/app/hadoop/tmp/mapred/local/1548125086275/mapper.py 19/01/22 10:44:46 INFO mapred.LocalDistributedCacheManager: Localized file:/home/andrew/code/HadoopWithPython/python/MapReduce/HadoopStreaming/reducer.py as file:/app/hadoop/tmp/mapred/local/1548125086276/reducer.py 19/01/22 10:44:46 INFO mapreduce.Job: The url to track the job: http://localhost:8080/ 19/01/22 10:44:46 INFO mapred.LocalJobRunner: OutputCommitter set in config null 19/01/22 10:44:46 INFO mapreduce.Job: Running job: job_local208759810_0001 19/01/22 10:44:46 INFO mapred.LocalJobRunner: OutputCommitter is org.apache.hadoop.mapred.FileOutputCommitter 19/01/22 10:44:46 INFO output.FileOutputCommitter: File Output Committer Algorithm version is 1 19/01/22 10:44:46 INFO output.FileOutputCommitter: FileOutputCommitter skip cleanup _temporary folders under output directory:false, ignore cleanup failures: false 19/01/22 10:44:46 INFO mapred.LocalJobRunner: Waiting for map tasks 19/01/22 10:44:46 INFO mapred.LocalJobRunner: Starting task: attempt_local208759810_0001_m_000000_0 19/01/22 10:44:46 INFO output.FileOutputCommitter: File Output Committer Algorithm version is 1 19/01/22 10:44:46 INFO output.FileOutputCommitter: FileOutputCommitter skip cleanup _temporary folders under output directory:false, ignore cleanup failures: false 19/01/22 10:44:46 INFO mapred.Task: Using ResourceCalculatorProcessTree : [ ] 19/01/22 10:44:46 INFO mapred.MapTask: Processing split: hdfs://localhost:54310/user/hduser/input2.txt:0+29 19/01/22 10:44:46 INFO mapred.MapTask: numReduceTasks: 1 19/01/22 10:44:46 INFO mapred.MapTask: (EQUATOR) 0 kvi 26214396(104857584) 19/01/22 10:44:46 INFO mapred.MapTask: mapreduce.task.io.sort.mb: 100 19/01/22 10:44:46 INFO mapred.MapTask: soft limit at 83886080 19/01/22 10:44:46 INFO mapred.MapTask: bufstart = 0; bufvoid = 104857600 19/01/22 10:44:46 INFO mapred.MapTask: kvstart = 26214396; length = 6553600 19/01/22 10:44:46 INFO mapred.MapTask: Map output collector class = org.apache.hadoop.mapred.MapTask$MapOutputBuffer 19/01/22 10:44:46 INFO streaming.PipeMapRed: PipeMapRed exec [/home/andrew/code/HadoopWithPython/python/MapReduce/HadoopStreaming/./mapper.py] 19/01/22 10:44:46 INFO Configuration.deprecation: mapred.work.output.dir is deprecated. Instead, use mapreduce.task.output.dir 19/01/22 10:44:46 INFO Configuration.deprecation: map.input.start is deprecated. Instead, use mapreduce.map.input.start 19/01/22 10:44:46 INFO Configuration.deprecation: mapred.task.is.map is deprecated. Instead, use mapreduce.task.ismap 19/01/22 10:44:46 INFO Configuration.deprecation: mapred.task.id is deprecated. Instead, use mapreduce.task.attempt.id 19/01/22 10:44:46 INFO Configuration.deprecation: mapred.tip.id is deprecated. Instead, use mapreduce.task.id 19/01/22 10:44:46 INFO Configuration.deprecation: mapred.local.dir is deprecated. Instead, use mapreduce.cluster.local.dir 19/01/22 10:44:46 INFO Configuration.deprecation: map.input.file is deprecated. Instead, use mapreduce.map.input.file 19/01/22 10:44:46 INFO Configuration.deprecation: mapred.skip.on is deprecated. Instead, use mapreduce.job.skiprecords 19/01/22 10:44:46 INFO Configuration.deprecation: map.input.length is deprecated. Instead, use mapreduce.map.input.length 19/01/22 10:44:46 INFO Configuration.deprecation: mapred.job.id is deprecated. Instead, use mapreduce.job.id 19/01/22 10:44:46 INFO Configuration.deprecation: user.name is deprecated. Instead, use mapreduce.job.user.name 19/01/22 10:44:46 INFO Configuration.deprecation: mapred.task.partition is deprecated. Instead, use mapreduce.task.partition 19/01/22 10:44:46 INFO streaming.PipeMapRed: R/W/S=1/0/0 in:NA [rec/s] out:NA [rec/s] 19/01/22 10:44:46 INFO streaming.PipeMapRed: Records R/W=1/1 19/01/22 10:44:46 INFO streaming.PipeMapRed: MRErrorThread done 19/01/22 10:44:46 INFO streaming.PipeMapRed: mapRedFinished 19/01/22 10:44:46 INFO mapred.LocalJobRunner: 19/01/22 10:44:46 INFO mapred.MapTask: Starting flush of map output 19/01/22 10:44:46 INFO mapred.MapTask: Spilling map output 19/01/22 10:44:46 INFO mapred.MapTask: bufstart = 0; bufend = 41; bufvoid = 104857600 19/01/22 10:44:46 INFO mapred.MapTask: kvstart = 26214396(104857584); kvend = 26214376(104857504); length = 21/6553600 19/01/22 10:44:46 INFO mapred.MapTask: Finished spill 0 19/01/22 10:44:46 INFO mapred.Task: Task:attempt_local208759810_0001_m_000000_0 is done. And is in the process of committing 19/01/22 10:44:46 INFO mapred.LocalJobRunner: Records R/W=1/1 19/01/22 10:44:46 INFO mapred.Task: Task 'attempt_local208759810_0001_m_000000_0' done. 19/01/22 10:44:46 INFO mapred.LocalJobRunner: Finishing task: attempt_local208759810_0001_m_000000_0 19/01/22 10:44:46 INFO mapred.LocalJobRunner: map task executor complete. 19/01/22 10:44:46 INFO mapred.LocalJobRunner: Waiting for reduce tasks 19/01/22 10:44:46 INFO mapred.LocalJobRunner: Starting task: attempt_local208759810_0001_r_000000_0 19/01/22 10:44:46 INFO output.FileOutputCommitter: File Output Committer Algorithm version is 1 19/01/22 10:44:46 INFO output.FileOutputCommitter: FileOutputCommitter skip cleanup _temporary folders under output directory:false, ignore cleanup failures: false 19/01/22 10:44:46 INFO mapred.Task: Using ResourceCalculatorProcessTree : [ ] 19/01/22 10:44:46 INFO mapred.ReduceTask: Using ShuffleConsumerPlugin: org.apache.hadoop.mapreduce.task.reduce.Shuffle@78674b51 19/01/22 10:44:46 INFO reduce.MergeManagerImpl: MergerManager: memoryLimit=334338464, maxSingleShuffleLimit=83584616, mergeThreshold=220663392, ioSortFactor=10, memToMemMergeOutputsThreshold=10 19/01/22 10:44:46 INFO reduce.EventFetcher: attempt_local208759810_0001_r_000000_0 Thread started: EventFetcher for fetching Map Completion Events 19/01/22 10:44:46 INFO reduce.LocalFetcher: localfetcher#1 about to shuffle output of map attempt_local208759810_0001_m_000000_0 decomp: 55 len: 59 to MEMORY 19/01/22 10:44:46 INFO reduce.InMemoryMapOutput: Read 55 bytes from map-output for attempt_local208759810_0001_m_000000_0 19/01/22 10:44:46 INFO reduce.MergeManagerImpl: closeInMemoryFile -> map-output of size: 55, inMemoryMapOutputs.size() -> 1, commitMemory -> 0, usedMemory ->55 19/01/22 10:44:46 INFO reduce.EventFetcher: EventFetcher is interrupted.. Returning 19/01/22 10:44:46 INFO mapred.LocalJobRunner: 1 / 1 copied. 19/01/22 10:44:46 INFO reduce.MergeManagerImpl: finalMerge called with 1 in-memory map-outputs and 0 on-disk map-outputs 19/01/22 10:44:46 INFO mapred.Merger: Merging 1 sorted segments 19/01/22 10:44:46 INFO mapred.Merger: Down to the last merge-pass, with 1 segments left of total size: 50 bytes 19/01/22 10:44:46 INFO reduce.MergeManagerImpl: Merged 1 segments, 55 bytes to disk to satisfy reduce memory limit 19/01/22 10:44:46 INFO reduce.MergeManagerImpl: Merging 1 files, 59 bytes from disk 19/01/22 10:44:46 INFO reduce.MergeManagerImpl: Merging 0 segments, 0 bytes from memory into reduce 19/01/22 10:44:46 INFO mapred.Merger: Merging 1 sorted segments 19/01/22 10:44:46 INFO mapred.Merger: Down to the last merge-pass, with 1 segments left of total size: 50 bytes 19/01/22 10:44:46 INFO mapred.LocalJobRunner: 1 / 1 copied. 19/01/22 10:44:46 INFO streaming.PipeMapRed: PipeMapRed exec [/home/andrew/code/HadoopWithPython/python/MapReduce/HadoopStreaming/./reducer.py] 19/01/22 10:44:46 INFO Configuration.deprecation: mapred.job.tracker is deprecated. Instead, use mapreduce.jobtracker.address 19/01/22 10:44:46 INFO Configuration.deprecation: mapred.map.tasks is deprecated. Instead, use mapreduce.job.maps 19/01/22 10:44:46 INFO streaming.PipeMapRed: R/W/S=1/0/0 in:NA [rec/s] out:NA [rec/s] 19/01/22 10:44:46 INFO streaming.PipeMapRed: Records R/W=6/1 19/01/22 10:44:46 INFO streaming.PipeMapRed: MRErrorThread done 19/01/22 10:44:46 INFO streaming.PipeMapRed: mapRedFinished 19/01/22 10:44:46 INFO mapred.Task: Task:attempt_local208759810_0001_r_000000_0 is done. And is in the process of committing 19/01/22 10:44:46 INFO mapred.LocalJobRunner: 1 / 1 copied. 19/01/22 10:44:46 INFO mapred.Task: Task attempt_local208759810_0001_r_000000_0 is allowed to commit now 19/01/22 10:44:46 INFO output.FileOutputCommitter: Saved output of task 'attempt_local208759810_0001_r_000000_0' to hdfs://localhost:54310/user/hduser/output2/_temporary/0/task_local208759810_0001_r_000000 19/01/22 10:44:46 INFO mapred.LocalJobRunner: Records R/W=6/1 > reduce 19/01/22 10:44:46 INFO mapred.Task: Task 'attempt_local208759810_0001_r_000000_0' done. 19/01/22 10:44:46 INFO mapred.LocalJobRunner: Finishing task: attempt_local208759810_0001_r_000000_0 19/01/22 10:44:46 INFO mapred.LocalJobRunner: reduce task executor complete. 19/01/22 10:44:47 INFO mapreduce.Job: Job job_local208759810_0001 running in uber mode : false 19/01/22 10:44:47 INFO mapreduce.Job: map 100% reduce 100% 19/01/22 10:44:47 INFO mapreduce.Job: Job job_local208759810_0001 completed successfully 19/01/22 10:44:47 INFO mapreduce.Job: Counters: 35 File System Counters FILE: Number of bytes read=273356 FILE: Number of bytes written=1217709 FILE: Number of read operations=0 FILE: Number of large read operations=0 FILE: Number of write operations=0 HDFS: Number of bytes read=58 HDFS: Number of bytes written=29 HDFS: Number of read operations=13 HDFS: Number of large read operations=0 HDFS: Number of write operations=4 Map-Reduce Framework Map input records=1 Map output records=6 Map output bytes=41 Map output materialized bytes=59 Input split bytes=97 Combine input records=0 Combine output records=0 Reduce input groups=4 Reduce shuffle bytes=59 Reduce input records=6 Reduce output records=4 Spilled Records=12 Shuffled Maps =1 Failed Shuffles=0 Merged Map outputs=1 GC time elapsed (ms)=0 Total committed heap usage (bytes)=552599552 Shuffle Errors BAD_ID=0 CONNECTION=0 IO_ERROR=0 WRONG_LENGTH=0 WRONG_MAP=0 WRONG_REDUCE=0 File Input Format Counters Bytes Read=29 File Output Format Counters Bytes Written=29 19/01/22 10:44:47 INFO streaming.StreamJob: Output directory: /user/hduser/output2 $ hdfs dfs -cat /user/hduser/output2/part-00000 be 2 jack 2 nimble 1 quick 1

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

[雪峰磁针石博客]大数据Hadoop工具python教程4-mrjob

mrjob是由Yelp创建的Python MapReduce库,它封装了Hadoop流,允许MapReduce应用程序以更加Pythonic的方式编写。 mrjob用纯Python编写多步MapReduce作业。使用mrjob编写的MapReduce作业可以在本地测试,在Hadoop集群上运行,或使用Amazon Elastic MapReduce(EMR)在云中运行。 使用mrjob编写MapReduce应用程序有许多好处: mrjob目前是非常活跃的框架,每周都有多次提交。 mrjob拥有丰富的文档。 可以在不安装Hadoop的情况下执行和测试mrjob应用程序,在部署到Hadoop集群之前就可开发和测试。 mrjob允许MapReduce应用程序在单个类中编写,而不是为mapper和reducer编写单独的程序。 虽然mrjob是很好的解决方案,但它确实有它的缺点。 mrjob是简化的,因此它不会提供与其他API提供的Hadoop相同级别的访问权限。 mrjob不使用typedbytes,因此其他库可能更快。 安装 $ pip install mrjob 参考资料 python测试开发项目实战-目录 python工具书籍下载-持续更新 python 3.7极速入门教程 - 目录 原文地址 本文涉及的python测试开发库 谢谢点赞! [本文相关海量书籍下载](https://github.com/china-testing/python-api-tesing/blob/master/books.md 单词统计 #!/usr/bin/env python # 项目实战讨论QQ群630011153 144081101 # https://github.com/china-testing/python-api-tesing from mrjob.job import MRJob class MRWordCount(MRJob): def mapper(self, _, line): for word in line.split(): yield(word, 1) def reducer(self, word, counts): yield(word, sum(counts)) if __name__ == '__main__': MRWordCount.run() 执行结果 $ python word_count.py /home/hduser_/input2.txt No configs found; falling back on auto-configuration No configs specified for inline runner Running step 1 of 1... Creating temp directory /tmp/word_count.hduser_.20190122.035729.128110 job output is in /tmp/word_count.hduser_.20190122.035729.128110/output Streaming final output from /tmp/word_count.hduser_.20190122.035729.128110/output... "nimble" 1 "be" 2 "quick" 1 "jack" 2 Removing temp directory /tmp/word_count.hduser_.20190122.035729.128110... 比较重要的方法有:mapper()、combiner()和reducer()。 多个输入文件: $ python mr_job.py input1.txt input2.txt input3.txt 默认情况下,mrjob在本地运行,允许在提交到Hadoop集群之前开发和调试代码。要更改作业的运行方式,请指定-r/--runner选项。 $ python mr_job.py -r hadoop hdfs://input/input.txt $ python mr_job.py -r emr s3://input-bucket/input.txt

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

[雪峰磁针石博客]python GUI作业:tkinter控件改变背景色

python测试开发项目实战-目录 python工具书籍下载-持续更新 python 3.7极速入门教程 - 目录 要求 使用tkinter生成如下窗口: 在右上角文本框输入名字,在旁边的下拉框选择数字,点击"Click Me!", "Click Me!"的文本将改变成如下: 可以选择"Unchecked"和"Enabled"的其中一个。 点击Blue、Gold、Red其中的一个,将会改变背景为对应的颜色。 最下面的文本框可以输入文本,当列数超出范围时,可以通过滚动条操作。 参考资料 本文最新版本地址 本文涉及的python测试开发库 谢谢点赞! 本文相关海量书籍下载 python工具书籍下载-持续更新 python GUI工具书籍下载-持续更新 参考代码 #!/usr/bin/python3 # -*- coding: utf-8 -*- # 技术支持:https://www.jianshu.com/u/69f40328d4f0 # 技术支持 https://china-testing.github.io/ # https://github.com/china-testing/python-api-tesing/blob/master/practices/tk/tk1.py # 项目实战讨论QQ群630011153 144081101 # CreateDate: 2018-11-27 import tkinter as tk from tkinter import ttk from tkinter import scrolledtext win = tk.Tk() # Add a title win.title("Python GUI") # Modify adding a Label a_label = ttk.Label(win, text="A Label") a_label.grid(column=0, row=0) # Modified Button Click Function def click_me(): action.configure(text='Hello ' + name.get() + ' ' + number_chosen.get()) # Changing our Label ttk.Label(win, text="Enter a name:").grid(column=0, row=0) # Adding a Textbox Entry widget name = tk.StringVar() name_entered = ttk.Entry(win, width=12, textvariable=name) name_entered.grid(column=0, row=1) # Adding a Button action = ttk.Button(win, text="Click Me!", command=click_me) action.grid(column=2, row=1) # <= change column to 2 # Creating three checkbuttons ttk.Label(win, text="Choose a number:").grid(column=1, row=0) number = tk.StringVar() number_chosen = ttk.Combobox(win, width=12, textvariable=number, state='readonly') number_chosen['values'] = (1, 2, 4, 42, 100) number_chosen.grid(column=1, row=1) number_chosen.current(3) chVarDis = tk.IntVar() check1 = tk.Checkbutton(win, text="Disabled", variable=chVarDis, state='disabled') check1.select() check1.grid(column=0, row=4, sticky=tk.W) chVarUn = tk.IntVar() check2 = tk.Checkbutton(win, text="UnChecked", variable=chVarUn) check2.deselect() check2.grid(column=1, row=4, sticky=tk.W) chVarEn = tk.IntVar() check3 = tk.Checkbutton(win, text="Enabled", variable=chVarEn) check3.deselect() check3.grid(column=2, row=4, sticky=tk.W) # GUI Callback function def checkCallback(*ignoredArgs): # only enable one checkbutton if chVarUn.get(): check3.configure(state='disabled') else: check3.configure(state='normal') if chVarEn.get(): check2.configure(state='disabled') else: check2.configure(state='normal') # trace the state of the two checkbuttons chVarUn.trace('w', lambda unused0, unused1, unused2 : checkCallback()) chVarEn.trace('w', lambda unused0, unused1, unused2 : checkCallback()) # First, we change our Radiobutton global variables into a list colors = ["Blue", "Gold", "Red"] # We have also changed the callback function to be zero-based, using the list # instead of module-level global variables # Radiobutton Callback def radCall(): radSel=radVar.get() win.configure(background=colors[radSel]) # create three Radiobuttons using one variable radVar = tk.IntVar() # Next we are selecting a non-existing index value for radVar radVar.set(99) # Now we are creating all three Radiobutton widgets within one loop for col in range(3): curRad = tk.Radiobutton(win, text=colors[col], variable=radVar, value=col, command=radCall) curRad.grid(column=col, row=5, sticky=tk.W) # Using a scrolled Text control scr = scrolledtext.ScrolledText(win, width=30, height=3, wrap=tk.WORD) scr.grid(column=0, columnspan=3) name_entered.focus() # Place cursor into name Entry #====================== # Start GUI #====================== win.mainloop()

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

[雪峰磁针石博客]python网络基础工具书籍下载-持续更新

爬虫书籍参见: 2018最佳人工智能数据采集(爬虫)工具书下载 Python Network Programming Cookbook, 2nd Edition - 2017.pdf 介绍了现实世界中几乎所有网络任务的真实示例,通过简明易懂的形式让读者掌握如何使用Python完成这些网络编程任务。具体说来,书中通过70多篇攻略讨论了Python网络编程的高阶话题,包括编写简单的网络客户端和服务器、HTTP协议网络编程、跨设备编程、屏幕抓取以及网络安全监控,等等。本书可以作为任何一门网络编程课程中培养实践技能的补充材料。《图灵程序设计丛书:Python网络编程攻略》需要读者对Python语言及TCP/IP等基本的网络概念有了解。 Practical Network Automation Leverage the power of Python and Ansible to optimize your network - 2017.pdf O'Reilly.Twisted.Network.Programming.Essentials.2nd.Edition.Mar.2013.pdf Learning Python Network Programming - 2015.pdf Foundations of Python Network Programming, 3rd Edition - 2014.pdf Data Science and Complex Networks Real Case Studies with Python - 2016.pdf 参考资料 讨论qq群144081101 591302926 567351477 钉钉免费群21745728 本文最新版本地址 本文涉及的python测试开发库 谢谢点赞! 本文相关海量书籍下载 Complex Network Analysis in Python Recognize – Construct – Visualize – Analyze – Interpret - 2018.pdf

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

[雪峰磁针石博客]使用jython进行dubbo接口及ngrinder性能测试

快速入门(接口测试) 确认mvn和jdk、jython安装ok。 先下载dubbo的demo,编译运行demo。 # git clone https://github.com/alibaba/dubbo.git dubbo # cd dubbo/ # mvn clean install -Dmaven.test.skip # cd dubbo-demo/dubbo-demo-provider/target/ # tar xzvf dubbo-demo-provider-2.5.4-SNAPSHOT-assembly.tar.gz # cd dubbo-demo-provider-2.5.4-SNAPSHOT/bin # ./start.sh # cd /opt/code/dubbo-demo/dubbo-demo-consumer/target/ # tar xzvf dubbo-demo-provider-2.5.4-SNAPSHOT-assembly.tar.gz # cd dubbo-demo-consumer-2.5.4-SNAPSHOT/bin # ./start.sh 注意:阿里的demo启动脚本有bug,如果启动时报进程已经存在,请修改start.sh中的grep部分,增加" | grep -v grep"。 确认在consumer的的日志可以看到"hello"输出,恭喜你,dubbo的demo已经成功。现在关闭上面程序,用eclipse或其他IDE打开工程进行修改。 安装zk, 下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper/ 下载完毕后解压,执行:"# ./zkServer.sh start" 修改工程 修改工程dubbo-demo-provider和dubbo-demo-consumer的dubbo.properties: dubbo.container=log4j,spring dubbo.application.name=demo-provider dubbo.application.owner=william #dubbo.registry.address=multicast://224.5.6.7:1234 dubbo.registry.address=zookeeper://127.0.0.1:2181 #dubbo.registry.address=redis://127.0.0.1:6379 #dubbo.registry.address=dubbo://127.0.0.1:9090 #dubbo.monitor.protocol=registry dubbo.protocol.name=dubbo dubbo.protocol.port=20880 dubbo.service.loadbalance=roundrobin #dubbo.log4j.file=logs/dubbo-demo-consumer.log #dubbo.log4j.level=WARN dubbo-demo-consumer的pom.xml加载的内容太多,需要进行精简,如下: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.alibaba</groupId> <artifactId>dubbo-demo</artifactId> <version>2.5.4-SNAPSHOT</version> </parent> <artifactId>dubbo-demo-consumer</artifactId> <packaging>jar</packaging> <name>${project.artifactId}</name> <description>The demo consumer module of dubbo project</description> <properties> <skip_maven_deploy>false</skip_maven_deploy> </properties> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo-demo-api</artifactId> <version>${project.parent.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>${project.parent.version}</version> </dependency> <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>unpack</id> <phase>package</phase> <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>${project.parent.version}</version> <outputDirectory>${project.build.directory}/dubbo</outputDirectory> <includes>META-INF/assembly/**</includes> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptor>src/main/assembly/assembly.xml</descriptor> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project> dubbo-demo-consumer工程新增demo.xml, 为jython访问dubbo的定义。 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:application name="hello-world-app" /> <dubbo:registry address="zookeeper://127.0.0.1:2181"/> <dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.DemoService" /> </beans> 新增jython脚本: from org.springframework.context.support import ClassPathXmlApplicationContext context = ClassPathXmlApplicationContext("demo.xml") service = context.getBean("demoService") print service.sayHello("How are you!") 重新执行第2步的编译,并在CLASSPATH添加对应的目录,比如: export CLASSPATH=$CLASSPATH:/opt/lib/* 在IDE中运行:DemoProvider 执行: $ jython dubbo_test.py "my" variable $jythonHome masks earlier declaration in same scope at /usr/bin/jython line 15. log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info. Hello How are you!, response form provider: 172.17.153.6:20880 java里面也可以采用这种方法。下面修改DemoConsumer类: package com.alibaba.dubbo.demo.consumer; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.alibaba.dubbo.demo.DemoService; public class DemoConsumer { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("demo.xml"); DemoService service = context.getBean(DemoService.class); System.out.println(service.sayHello("How are you!")); } } 可见java的操作和jython是极其类似的,只是在实际测试中,java改动需要频繁,带来不少不便。实际应用通常把多个包含dubbo服务定义的文件放在一个jar包中,这样一个jython就可以灵活地测试多个dubbo接口。当然不同接口要加载的jar是不同的,好在jython可以动态修改CLASSPATH, 参见:http://www.jython.org/jythonbook/en/1.0/appendixB.html#working-with-classpath。 Jmeter做dubbo性能测试就可以用上面这种方法,继承AbstractJavaSamplerClient类就可以。参考资料如下: http://jmeter.apache.org/api/ 下面是一个实际使用的jython接口测试脚本: #!/usr/local/jython/bin/jython # -*- coding: utf-8 -*- # Author Rongzhong Xu 2016-09-06 wechat: pythontesting """ Name: dubbo.py Tesed in python3.5 """ from org.springframework.context.support import ClassPathXmlApplicationContext from com.oppo.sso.model.request import SecurityRequest context = ClassPathXmlApplicationContext("onekey-register-consumer.xml") service = context.getBean("registerService") request = SecurityRequest() request.setMobile("13244448888") request.setApplicationKey("test") request.setCreateBy("127.0.0.1") request.setCreateIP("127.0.0.1") print("{0} {1} {0}".format("="*30, "Result(")) print(service.register(request)) result = service.register(request) print(result.getResultCode()) print(result.getResultDesc()) 性能测试支持 这里对nGrinder不做入门介绍,相关资料请参考:测试工具nGrinder介绍 nGrinder管理库的方式和grinder并不一样。可以通过web操作,但是如果文件较多的话,还是建议使用svn。 在nGrinder的web页面点击"脚本",选中测试目标之后,里面有个"TestRunner.py"之类的脚本,在当前目前新建lib目录,jar包和python库文件都可以扔到这里,这样nGrinder就可以访问了。 上面demo的测试脚本如下: # -*- coding:utf-8 -*- # A simple example using the HTTP plugin that shows the retrieval of a # single page via HTTP. # # This script is automatically generated by ngrinder. # # @author admin from net.grinder.script.Grinder import grinder from net.grinder.script import Test from net.grinder.plugin.http import HTTPRequest from net.grinder.plugin.http import HTTPPluginControl from java.util import Date from HTTPClient import NVPair, Cookie, CookieModule from org.springframework.context.support import ClassPathXmlApplicationContext control = HTTPPluginControl.getConnectionDefaults() # if you don't want that HTTPRequest follows the redirection, please modify the following option 0. # control.followRedirects = 1 # if you want to increase the timeout, please modify the following option. control.timeout = 6000 test1 = Test(1, "127.0.0.1") request1 = HTTPRequest() # Set header datas headers = [] # Array of NVPair # Set param datas params = [] # Array of NVPair # Set cookie datas cookies = [] # Array of Cookie class TestRunner: # initlialize a thread def __init__(self): test1.record(TestRunner.__call__) grinder.statistics.delayReports=True context = ClassPathXmlApplicationContext("demo.xml") self.service = context.getBean("demoService") def before(self): request1.headers = headers for c in cookies: CookieModule.addCookie(c, HTTPPluginControl.getThreadHTTPClientContext()) # test method def __call__(self): self.before() result = self.service.sayHello("How are you!") print result jython英文教程: http://www.jython.org/jythonbook/en/1.0/ 参考资料 本文最新版本地址 本文涉及的python测试开发库 谢谢点赞! 本文相关海量书籍下载 2018最佳人工智能机器学习工具书及下载(持续更新) 接口测试面试题.pdf 软件测试精品书籍下载 python通过协议支持dubbo接口 以下方式支持dubbo的部分协议,序列化是个难点。 # git clone https://github.com/alibaba/dubbo.git dubbo # cd dubbo/ # mvn clean install -Dmaven.test.skip # cd dubbo-demo/dubbo-demo-provider/target/ # tar xzvf dubbo-demo-provider-2.5.4-SNAPSHOT-assembly.tar.gz # cd dubbo-demo-provider-2.5.4-SNAPSHOT/bin # ./start.sh # cd /opt/code/dubbo-demo/dubbo-demo-consumer/target/ # tar xzvf dubbo-demo-provider-2.5.4-SNAPSHOT-assembly.tar.gz # cd dubbo-demo-consumer-2.5.4-SNAPSHOT/bin # ./start.sh python环境安装 # git clone https://github.com/dmall/dudubbo # cd dudubbo/ # git checkout remotes/origin/feature/block-socket # python3 setup.py install python测试 # /opt/python3.5/bin/python3 Python 3.5.1 (default, May 19 2016, 11:47:26) [GCC 4.4.7 20120313 (Red Hat 4.4.7-16)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from dubbo import Dubbo >>> from dubbo._model import Object >>> config = { 'classpath' : '/data/code/dubbo/dubbo-demo/dubbo-demo-api/target/dubbo-demo-api-2.5.4-SNAPSHOT.jar' } >>> client = Dubbo((('localhost', 20880),), config, enable_heartbeat=True) >>> q = client.getProxy('com.alibaba.dubbo.demo.DemoService') >>> type(q) <class 'dubbo.dubbo.ServiceProxy'> >>> q.sayHello("Test") Connected to localhost:20880 successfully 'Hello Test, response form provider: 10.51.51.152:20880'

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

[雪峰磁针石博客]Bokeh数据可视化工具1快速入门

简介 数据可视化python库参考 python数据可视化库最突出的为Matplotlib、Seaborn和Bokeh。前两个,Matplotlib和Seaborn,绘制静态图。Bokeh可以绘制交互式图。 安装 conda install bokeh pip2 install bokeh pip3 install bokeh 检验安装 from bokeh.plotting import figure, output_file, show #HTML file to output your plot into output_file("bokeh.html") #Constructing a basic line plot x = [1,2,3] y = [4,5,6] p = figure() p.line(x,y) show(p) image.png 问题讨论: https://groups.google.com/a/anaconda.com/forum/#!forum/bokeh bug跟踪:https://github.com/bokeh/bokeh/issues 应用程序:Bokeh应用程序是在浏览器中运行的Bokeh渲染文档 Glyph:Glyph是Bokeh的基石,它们是线条,圆形,矩形等。 服务器:Bokeh服务器用于共享和发布交互式图表 小部件Widgets::Bokeh中的小部件是滑块,下拉菜单等 输出方法有:output_file('plot.html')和output_notebook() 构建图片的方式: #Code to construct a figure from bokeh.plotting import figure # create a Figure object p = figure(plot_width=500, plot_height=400, tools="pan,hover") 绘图基础 线状图 #Creating a line plot #Importing the required packages from bokeh.io import output_file, show from bokeh.plotting import figure #Creating our data arrays used for plotting the line plot x = [5,6,7,8,9,10] y = [1,2,3,4,5,6] #Calling the figure() function to create the figure of the plot plot = figure() #Creating a line plot using the line() function plot.line(x,y) #Creating markers on our line plot at the location of the intersection between x and y plot.cross(x,y, size = 15) #Output the plot output_file('line_plot.html') show(plot) image.png 柱形图 #Creating bar plots #Importing the required packages from bokeh.plotting import figure, show, output_file #Points on the x axis x = [8,9,10] #Points on the y axis y = [1,2,3] #Creating the figure of the plot plot = figure() #Code to create the barplot plot.vbar(x,top = y, color = "blue", width= 0.5) #Output the plot output_file('barplot.html') show(plot) image.png 补丁图 #Creating patch plots #Importing the required packages from bokeh.io import output_file, show from bokeh.plotting import figure #Creating the regions to map x_region = [[1,1,2,], [2,3,4], [2,3,5,4]] y_region = [[2,5,6], [3,6,7], [2,4,7,8]] #Creating the figure plot = figure() #Building the patch plot plot.patches(x_region, y_region, fill_color = ['yellow', 'black', 'green'], line_color = 'white') #Output the plot output_file('patch_plot.html') show(plot) image.png 散列图 #Creating scatter plots #Importing the required packages from bokeh.io import output_file, show from bokeh.plotting import figure #Creating the figure plot = figure() #Creating the x and y points x = [1,2,3,4,5] y = [5,7,2,2,4] #Plotting the points with a cirle marker plot.circle(x,y, size = 30) #Output the plot output_file('scatter.html') show(plot) image.png 更多资源 #- cross() #- x() #- diamond() #- diamond_cross() #- circle_x() #- circle_cross() #- triangle() #- inverted_triangle() #- square() #- square_x() #- square_cross() #- asterisk() #Adding labels to the plot plot.figure(x_axis_label = "Label name of x axis", y_axis_label = "Label name of y axis") #Customizing transperancy of the plot plot.circle(x, y, alpha = 0.5) plot.circle(x, y, alpha = 0.5) 参考资料 本文最新版本地址 讨论 钉钉免费群21745728 qq群144081101 567351477 本文涉及的python测试开发库 谢谢点赞! 本文相关海量书籍下载 代码仓库

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

[雪峰磁针石博客]python标准模块介绍-string:文本常量和模板

string—文本常量和模板 作用:包含处理文本的常量和类。 Python版本:1.4及以后版本 最早的Python版本就有string模块。 之前在这个模块中实现的许多函数已经移至str对象的方法。 string模块保留了几个有用的常量和类,用于处理str对象。 代码地址 函数 capwords()的将字符串中所有单词的首字母大写。 #!python >>> import string >>> t = "hello world!" >>> string.capwords(t) 'Hello World!' >>> t 'hello world!' >>> t.capitalize() 'Hello world!' >>> t 'hello world!' 结果等同于先调用split(),把结果列表中各个单词的首字母大写,然后调用join()合并结果。 因为str对象已经有capitalize()方法,该函数的实际意义并不大。 模板 字符串模板已经作为PEP 292的一部分增加到Python 2.4中,并得到扩展,以替代内置拼接(interpolation)语法类似。使用string.Template拼接时,可以在变量名前面加上前缀$(如$var)来标识变量,如果需要与两侧的文本相区分,还可以用大括号将变量括起(如${var})。 下面的例子对简单的模板和使用%操作符及str.format()进行了比较。 #!python import string values = {'var': 'foo'} t = string.Template(""" Variable : $var Escape : $$ Variable in text: ${var}iable """) print('TEMPLATE:', t.substitute(values)) s = """ Variable : %(var)s Escape : %% Variable in text: %(var)siable """ print('INTERPOLATION:', s % values) s = """ Variable : {var} Escape : {{}} Variable in text: {var}iable """ print('FORMAT:', s.format(**values)) """ print 'INTERPOLATION:', s % values 执行结果: #!python python3 string_template.py TEMPLATE: Variable : foo Escape : $ Variable in text: fooiable INTERPOLATION: Variable : foo Escape : % Variable in text: fooiable FORMAT: Variable : foo Escape : {} Variable in text: fooiable 模板与标准字符串拼接的重要区别是模板不考虑参数类型。模板中值会转换为字符串且没有提供格式化选项。例如没有办法控制使用几位有效数字来表示浮点数值。 通过使用safe_substitute()方法,可以避免未能提供模板所需全部参数值时可能产生的异常。 tring_template_missing.py #!python import string values = {'var': 'foo'} t = string.Template("$var is here but $missing is not provided") try: print('substitute() :', t.substitute(values)) except KeyError as err: print('ERROR:', str(err)) print('safe_substitute():', t.safe_substitute(values)) 由于values字典中没有对应missing的值,因此substitute()会产生KeyError。不过,safe_substitute()不会抛出这个错误,它将捕获这个异常,并在文本中保留变量表达式。 #!python $ python3 string_template_missing.py ERROR: 'missing' safe_substitute(): foo is here but $missing is not provided 高级模板(非常用) 可以修改string.Template的默认语法,为此要调整它在模板体中查找变量名所使用的正则表达式模式。简单的做法是修改delimiter和idpattern类属性。 string_template_advanced.py #!python import string class MyTemplate(string.Template): delimiter = '%' idpattern = '[a-z]+_[a-z]+' template_text = ''' Delimiter : %% Replaced : %with_underscore Ignored : %notunderscored ''' d = { 'with_underscore': 'replaced', 'notunderscored': 'not replaced', } t = MyTemplate(template_text) print('Modified ID pattern:') print(t.safe_substitute(d)) 执行结果: #!python $ python3 string_template_advanced.py Modified ID pattern: Delimiter : % Replaced : replaced Ignored : %notunderscored 默认模式 #!python >>> import string >>> t = string.Template('$var') >>> print(t.pattern.pattern) \$(?: (?P<escaped>\$) | # Escape sequence of two delimiters (?P<named>(?-i:[_a-zA-Z][_a-zA-Z0-9]*)) | # delimiter and a Python identifier {(?P<braced>(?-i:[_a-zA-Z][_a-zA-Z0-9]*))} | # delimiter and a braced identifier (?P<invalid>) # Other ill-formed delimiter exprs ) string_template_newsyntax.py #!python import re import string class MyTemplate(string.Template): delimiter = '{{' pattern = r''' \{\{(?: (?P<escaped>\{\{)| (?P<named>[_a-z][_a-z0-9]*)\}\}| (?P<braced>[_a-z][_a-z0-9]*)\}\}| (?P<invalid>) ) ''' t = MyTemplate(''' {{{{ {{var}} ''') print('MATCHES:', t.pattern.findall(t.template)) print('SUBSTITUTED:', t.safe_substitute(var='replacement')) 执行结果: #!python $ python3 string_template_newsyntax.py MATCHES: [('{{', '', '', ''), ('', 'var', '', '')] SUBSTITUTED: {{ replacement 格式化 Formatter类实现与str.format()类似。 其功能包括类型转换,对齐,属性和字段引用,命名和位置模板参数以及特定类型的格式选项。 大多数情况下,fformat()方法是这些功能的更方便的接口,但是Formatter是作为父类,用于需要变化的情况。 常量 string模块包含许多与ASCII和数字字符集有关的常量。 string_constants.py #!python #!/usr/bin/env python3 # -*- coding: utf-8 -*- # Author: xurongzhong#126.com wechat:pythontesting qq:37391319 # 技术支持 钉钉群:21745728(可以加钉钉pythontesting邀请加入) # qq群:144081101 591302926 567351477 # CreateDate: 2018-6-12 import inspect import string def is_str(value): return isinstance(value, str) for name, value in inspect.getmembers(string, is_str): if name.startswith('_'): continue print('%s=%r\n' % (name, value)) 执行结果 #!python $ python3 string_constants.py ascii_letters='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ascii_lowercase='abcdefghijklmnopqrstuvwxyz' ascii_uppercase='ABCDEFGHIJKLMNOPQRSTUVWXYZ' digits='0123456789' hexdigits='0123456789abcdefABCDEF' octdigits='01234567' printable='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c' punctuation='!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' whitespace=' \t\n\r\x0b\x0c' 参考资料 本文最新版本地址 本文涉及的python测试开发库 谢谢点赞! 本文相关海量书籍下载 讨论 钉钉免费群21745728 qq群144081101 567351477 Standard library documentation for string String Methods – Methods of str objects that replace the deprecated functions in string. PEP 292 – Simpler String Substitutions Format String Syntax – The formal definition of the layout specification language used by Formatter and str.format().

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

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部分的功能。

用户登录
用户注册