首页 文章 精选 留言 我的

精选列表

搜索[高级威胁检测系统],共10025篇文章
优秀的个人博客,低调大师

python 高级教程

类 !/usr/bin/python -- coding: UTF-8 -- class Employee: '所有员工的基类' empCount = 0 def init(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary !/usr/bin/python -- coding: UTF-8 -- class Employee: '所有员工的基类' empCount = 0 def init(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary "创建 Employee 类的第一个对象" emp1 = Employee("Zara", 2000) "创建 Employee 类的第二个对象" emp2 = Employee("Manni", 5000) emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount 正则表达式 Python 正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。 Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。 re 模块使 Python 语言拥有全部的正则表达式功能。 compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。 re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。 本章节主要介绍Python中常用的正则表达式处理函数。 re.match函数 re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。 函数语法: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">re.match(pattern, string, flags=0)</pre> 函数参数说明: | 参数 | 描述 | | pattern | 匹配的正则表达式 | | string | 要匹配的字符串。 | | flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志 | 匹配成功re.match方法返回一个匹配的对象,否则返回None。 我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。 | 匹配对象方法 | 描述 | | group(num=0) | 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 | | groups() | 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。 | 实例 !/usr/bin/python # -- coding: UTF-8 -- import re print(re.match('www', 'www.runoob.com').span()) # 在起始位置匹配 print(re.match('com', 'www.runoob.com')) # 不在起始位置匹配 以上实例运行输出结果为: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">(0, 3) None</pre> 实例 !/usr/bin/python import re line = "Cats are smarter than dogs" matchObj = re.match( r'(.) are (.?) .*', line, re.M|re.I) if matchObj: print "matchObj.group() : ", matchObj.group() print "matchObj.group(1) : ", matchObj.group(1) print "matchObj.group(2) : ", matchObj.group(2) else: print "No match!!" 以上实例执行结果如下: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">matchObj.group() : Cats are smarter than dogs matchObj.group(1) : Cats matchObj.group(2) : smarter</pre> re.search方法 re.search 扫描整个字符串并返回第一个成功的匹配。 函数语法: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">re.search(pattern, string, flags=0)</pre> 函数参数说明: | 参数 | 描述 | | pattern | 匹配的正则表达式 | | string | 要匹配的字符串。 | | flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。 | 匹配成功re.search方法返回一个匹配的对象,否则返回None。 我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。 | 匹配对象方法 | 描述 | | group(num=0) | 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 | | groups() | 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。 | 实例 !/usr/bin/python # -- coding: UTF-8 -- import re print(re.search('www', 'www.runoob.com').span()) # 在起始位置匹配 print(re.search('com', 'www.runoob.com').span()) # 不在起始位置匹配 以上实例运行输出结果为: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">(0, 3) (11, 14)</pre> 实例 !/usr/bin/python import re line = "Cats are smarter than dogs"; searchObj = re.search( r'(.) are (.?) .*', line, re.M|re.I) if searchObj: print "searchObj.group() : ", searchObj.group() print "searchObj.group(1) : ", searchObj.group(1) print "searchObj.group(2) : ", searchObj.group(2) else: print "Nothing found!!" 以上实例执行结果如下: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">searchObj.group() : Cats are smarter than dogs searchObj.group(1) : Cats searchObj.group(2) : smarter</pre> re.match与re.search的区别 re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。 实例 !/usr/bin/python import re line = "Cats are smarter than dogs"; matchObj = re.match( r'dogs', line, re.M|re.I) if matchObj: print "match --> matchObj.group() : ", matchObj.group() else: print "No match!!" matchObj = re.search( r'dogs', line, re.M|re.I) if matchObj: print "search --> matchObj.group() : ", matchObj.group() else: print "No match!!" 以上实例运行结果如下: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">No match!! search --> matchObj.group() : dogs</pre> 检索和替换 Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。 语法: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">re.sub(pattern, repl, string, count=0, flags=0)</pre> 参数: pattern : 正则中的模式字符串。 repl : 替换的字符串,也可为一个函数。 string : 要被查找替换的原始字符串。 count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。 实例 !/usr/bin/python # -- coding: UTF-8 -- import re phone = "2004-959-559 # 这是一个国外电话号码" # 删除字符串中的 Python注释 num = re.sub(r'#.*$', "", phone) print "电话号码是: ", num # 删除非数字(-)的字符串 num = re.sub(r'\D', "", phone) print "电话号码是 : ", num 以上实例执行结果如下: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">电话号码是: 2004-959-559 电话号码是 : 2004959559</pre> repl 参数是一个函数 以下实例中将字符串中的匹配的数字乘以 2: 实例 !/usr/bin/python # -- coding: UTF-8 -- import re # 将匹配的数字乘以 2 def double(matched): value = int(matched.group('value')) return str(value * 2) s = 'A23G4HFD567' print(re.sub('(?P<value>\d+)', double, s)) 执行输出结果为: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">A46G8HFD1134</pre> re.compile 函数 compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。 语法格式为: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">re.compile(pattern[, flags])</pre> 参数: pattern : 一个字符串形式的正则表达式 flags : 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为: re.I 忽略大小写 re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境 re.M 多行模式 re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符) re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库 re.X 为了增加可读性,忽略空格和 # 后面的注释 实例 实例 import re >>> pattern = re.compile(r'\d+') # 用于匹配至少一个数字 >>> m = pattern.match('one12twothree34four') # 查找头部,没有匹配 >>> print m None >>> m = pattern.match('one12twothree34four', 2, 10) # 从'e'的位置开始匹配,没有匹配 >>> print m None >>> m = pattern.match('one12twothree34four', 3, 10) # 从'1'的位置开始匹配,正好匹配 >>> print m # 返回一个 Match 对象 <_sre.SRE_Match object at 0x10a42aac0> >>> m.group(0) # 可省略 0 '12' >>> m.start(0) # 可省略 0 3 >>> m.end(0) # 可省略 0 5 >>> m.span(0) # 可省略 0 (3, 5) 在上面,当匹配成功时返回一个 Match 对象,其中: group([group1, …]) 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0); start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0; end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0; span([group]) 方法返回 (start(group), end(group))。 再看看一个例子: 实例 import re >>> pattern = re.compile(r'([a-z]+) ([a-z]+)', re.I) # re.I 表示忽略大小写 >>> m = pattern.match('Hello World Wide Web') >>> print m # 匹配成功,返回一个 Match 对象 <_sre.SRE_Match object at 0x10bea83e8> >>> m.group(0) # 返回匹配成功的整个子串 'Hello World' >>> m.span(0) # 返回匹配成功的整个子串的索引 (0, 11) >>> m.group(1) # 返回第一个分组匹配成功的子串 'Hello' >>> m.span(1) # 返回第一个分组匹配成功的子串的索引 (0, 5) >>> m.group(2) # 返回第二个分组匹配成功的子串 'World' >>> m.span(2) # 返回第二个分组匹配成功的子串 (6, 11) >>> m.groups() # 等价于 (m.group(1), m.group(2), ...) ('Hello', 'World') >>> m.group(3) # 不存在第三个分组 Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: no such group findall 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。 注意: match 和 search 是匹配一次 findall 匹配所有。 语法格式为: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">findall(string[, pos[, endpos]])</pre> 参数: string : 待匹配的字符串。 pos : 可选参数,指定字符串的起始位置,默认为 0。 endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。 查找字符串中的所有数字: 实例 -- coding:UTF8 -- import re pattern = re.compile(r'\d+') # 查找数字 result1 = pattern.findall('runoob 123 google 456') result2 = pattern.findall('run88oob123google456', 0, 10) print(result1) print(result2) 输出结果: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">['123', '456'] ['88', '12']</pre> re.finditer 和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。 <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">re.finditer(pattern, string, flags=0)</pre> 参数: | 参数 | 描述 | | pattern | 匹配的正则表达式 | | string | 要匹配的字符串。 | | flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志 | 实例 -- coding: UTF-8 -- import re it = re.finditer(r"\d+","12a32bc43jf3") for match in it: print (match.group() ) 输出结果: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">12 32 43 3</pre> re.split split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 15px auto; padding: 10px 15px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251);">re.split(pattern, string[, maxsplit=0, flags=0])</pre> 参数: | 参数 | 描述 | | pattern | 匹配的正则表达式 | | string | 要匹配的字符串。 | | maxsplit | 分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。 | | flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志 | 实例 import re >>> re.split('\W+', 'runoob, runoob, runoob.') ['runoob', 'runoob', 'runoob', ''] >>> re.split('(\W+)', ' runoob, runoob, runoob.') ['', ' ', 'runoob', ', ', 'runoob', ', ', 'runoob', '.', ''] >>> re.split('\W+', ' runoob, runoob, runoob.', 1) ['', 'runoob, runoob, runoob.'] >>> re.split('a*', 'hello world') # 对于一个找不到匹配的字符串而言,split 不会对其作出分割 ['hello world'] 正则表达式对象 re.RegexObject re.compile() 返回 RegexObject 对象。 re.MatchObject group() 返回被 RE 匹配的字符串。 start() 返回匹配开始的位置 end() 返回匹配结束的位置 span() 返回一个元组包含匹配 (开始,结束) 的位置 正则表达式修饰符 - 可选标志 正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志: | 修饰符 | 描述 | | re.I | 使匹配对大小写不敏感 | | re.L | 做本地化识别(locale-aware)匹配 | | re.M | 多行匹配,影响 ^ 和 $ | | re.S | 使 . 匹配包括换行在内的所有字符 | | re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. | | re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 | 正则表达式模式 模式字符串使用特殊的语法来表示一个正则表达式: 字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。 多数字母和数字前加一个反斜杠时会拥有不同的含义。 标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。 反斜杠本身需要使用反斜杠转义。 由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r'\t',等价于 '\t')匹配相应的特殊字符。 下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。 | 模式 | 描述 | | ^ | 匹配字符串的开头 | | $ | 匹配字符串的末尾。 | | . | 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。 | | [...] | 用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k' | | [^...] | 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。 | | re* | 匹配0个或多个的表达式。 | | re+ | 匹配1个或多个的表达式。 | | re? | 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式 | | re{ n} | 精确匹配 n 个前面表达式。例如, o{2} 不能匹配 "Bob" 中的 "o",但是能匹配 "food" 中的两个 o。 | | re{ n,} | 匹配 n 个前面表达式。例如, o{2,} 不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有 o。"o{1,}" 等价于 "o+"。"o{0,}" 则等价于 "o*"。 | | re{ n, m} | 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式 | | a| b | 匹配a或b | | (re) | 匹配括号内的表达式,也表示一个组 | | (?imx) | 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。 | | (?-imx) | 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。 | | (?: re) | 类似 (...), 但是不表示一个组 | | (?imx: re) | 在括号中使用i, m, 或 x 可选标志 | | (?-imx: re) | 在括号中不使用i, m, 或 x 可选标志 | | (?#...) | 注释. | | (?= re) | 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。 | | (?! re) | 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功 | | (?> re) | 匹配的独立模式,省去回溯。 | | \w | 匹配字母数字及下划线 | | \W | 匹配非字母数字及下划线 | | \s | 匹配任意空白字符,等价于 [\t\n\r\f]. | | \S | 匹配任意非空字符 | | \d | 匹配任意数字,等价于 [0-9]. | | \D | 匹配任意非数字 | | \A | 匹配字符串开始 | | \Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。 | | \z | 匹配字符串结束 | | \G | 匹配最后匹配完成的位置。 | | \b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 | | \B | 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 | | \n, \t, 等. | 匹配一个换行符。匹配一个制表符。等 | | \1...\9 | 匹配第n个分组的内容。 | | \10 | 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。 | 正则表达式实例 字符匹配 | 实例 | 描述 | | python | 匹配 "python". | 字符类 | 实例 | 描述 | | [Pp]ython | 匹配 "Python" 或 "python" | | rub[ye] | 匹配 "ruby" 或 "rube" | | [aeiou] | 匹配中括号内的任意一个字母 | | [0-9] | 匹配任何数字。类似于 [0123456789] | | [a-z] | 匹配任何小写字母 | | [A-Z] | 匹配任何大写字母 | | [a-zA-Z0-9] | 匹配任何字母及数字 | | [^aeiou] | 除了aeiou字母以外的所有字符 | | [^0-9] | 匹配除了数字外的字符 | 特殊字符类 | 实例 | 描述 | | . | 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。 | | \d | 匹配一个数字字符。等价于 [0-9]。 | | \D | 匹配一个非数字字符。等价于 [^0-9]。 | | \s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 | | \S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 | | \w | 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。 | | \W | 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。 | Python 面向对象 Python CGI编程 2 篇笔记 jim 264***7522@qq.com 正则表达式实例: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 3px 0px 5px; padding: 7px 10px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251); border-radius: 1px;">#!/usr/bin/python import re line = "Cats are smarter than dogs" matchObj = re.match( r'(.) are (.?) .*', line, re.M|re.I) if matchObj: print "matchObj.group() : ", matchObj.group() print "matchObj.group(1) : ", matchObj.group(1) print "matchObj.group(2) : ", matchObj.group(2) else: print "No match!!"</pre> 正则表达式: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 3px 0px 5px; padding: 7px 10px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251); border-radius: 1px;">r'(.) are (.?) .*'</pre> 解析: 首先,这是一个字符串,前面的一个 r 表示字符串为非转义的原始字符串,让编译器忽略反斜杠,也就是忽略转义字符。但是这个字符串里没有反斜杠,所以这个 r 可有可无。 (.)* 第一个匹配分组,.* 代表匹配除换行符之外的所有字符。 (.?)* 第二个匹配分组,.*? 后面多个问号,代表非贪婪模式,也就是说只匹配符合条件的最少字符 后面的一个 .* 没有括号包围,所以不是分组,匹配效果和第一个一样,但是不计入匹配结果中。 matchObj.group() 等同于 matchObj.group(0),表示匹配到的完整文本字符 matchObj.group(1) 得到第一组匹配结果,也就是(.*)匹配到的 matchObj.group(2) 得到第二组匹配结果,也就是(.*?)匹配到的 因为只有匹配结果中只有两组,所以如果填 3 时会报错。 [jim](javascript:;) jim 264***7522@qq.com 1年前 (2017-04-24) CrazyDemo 444***899@qq.com '(?P<name>...)'</name> 分组匹配 例:身份证 1102231990xxxxxxxx <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 3px 0px 5px; padding: 7px 10px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251); border-radius: 1px;">import re s = '1102231990xxxxxxxx' res = re.search('(?P<province>\d{3})(?P<city>\d{3})(?P<born_year>\d{3})',s) print(res.groupdict())</pre> 此分组取出结果为: <pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); border-image: initial; margin: 3px 0px 5px; padding: 7px 10px; font: 12px/20px Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; background: url("/images/codecolorer_bg.gif") center top rgb(251, 251, 251); border-radius: 1px;">{'province': '110', 'city': '223', 'born_year': '199'}</pre> 直接将匹配结果直接转为字典模式,方便使用。 python cgi编程 获取mysql版本号 !/usr/bin/python -- coding: UTF-8 -- import MySQLdb 打开数据库连接 db = MySQLdb.connect("localhost", "testuser", "test123", "TESTDB", charset='utf8' ) 使用cursor()方法获取操作游标 cursor = db.cursor() 使用execute方法执行SQL语句 cursor.execute("SELECT VERSION()") 使用 fetchone() 方法获取一条数据 data = cursor.fetchone() print "Database version : %s " % data 关闭数据库连接 db.close() 创建数据库表: !/usr/bin/python -- coding: UTF-8 -- import MySQLdb 打开数据库连接 db = MySQLdb.connect("localhost", "testuser", "test123", "TESTDB", charset='utf8' ) 使用cursor()方法获取操作游标 cursor = db.cursor() 如果数据表已经存在使用 execute() 方法删除表。 cursor.execute("DROP TABLE IF EXISTS EMPLOYEE") 创建数据表SQL语句 sql = """CREATE TABLE EMPLOYEE ( FIRST_NAME CHAR(20) NOT NULL, LAST_NAME CHAR(20), AGE INT, SEX CHAR(1), INCOME FLOAT )""" cursor.execute(sql) 关闭数据库连接 db.close() 数据库插入语句 !/usr/bin/python -- coding: UTF-8 -- import MySQLdb 打开数据库连接 db = MySQLdb.connect("localhost", "testuser", "test123", "TESTDB", charset='utf8' ) 使用cursor()方法获取操作游标 cursor = db.cursor() SQL 插入语句 sql = "INSERT INTO EMPLOYEE(FIRST_NAME, LAST_NAME, AGE, SEX, INCOME) VALUES ('%s', '%s', '%d', '%c', '%d' )" % ('Mac', 'Mohan', 20, 'M', 2000) try: 执行sql语句 cursor.execute(sql) 提交到数据库执行 db.commit() except: 发生错误时回滚 db.rollback() 关闭数据库连接 db.close() 数据库查询 !/usr/bin/python -- coding: UTF-8 -- import MySQLdb 打开数据库连接 db = MySQLdb.connect("localhost", "testuser", "test123", "TESTDB", charset='utf8' ) 使用cursor()方法获取操作游标 cursor = db.cursor() SQL 查询语句 sql = "SELECT * FROM EMPLOYEE WHERE INCOME > '%d'" % (1000) try: 执行SQL语句 cursor.execute(sql) 获取所有记录列表 results = cursor.fetchall() for row in results: fname = row[0] lname = row[1] age = row[2] sex = row[3] income = row[4] # 打印结果 print "fname=%s,lname=%s,age=%d,sex=%s,income=%d" % (fname, lname, age, sex, income ) except: print "Error: unable to fecth data" 关闭数据库连接 db.close() python 网络编程 image.png 发送邮件 !/usr/bin/python -- coding: UTF-8 -- import smtplib from email.mime.text import MIMEText from email.header import Header sender = 'from@runoob.com' receivers = ['429240967@qq.com'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码 message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8') message['From'] = Header("菜鸟教程", 'utf-8') # 发送者 message['To'] = Header("测试", 'utf-8') # 接收者 subject = 'Python SMTP 邮件测试' message['Subject'] = Header(subject, 'utf-8') try: smtpObj = smtplib.SMTP('localhost') smtpObj.sendmail(sender, receivers, message.as_string()) print "邮件发送成功" except smtplib.SMTPException: print "Error: 无法发送邮件" 发送邮件: !/usr/bin/python -- coding: UTF-8 -- import smtplib from email.mime.text import MIMEText from email.header import Header 第三方 SMTP 服务 mail_host="smtp.XXX.com" #设置服务器 mail_user="XXXX" #用户名 mail_pass="XXXXXX" #口令 sender = 'from@runoob.com' receivers = ['429240967@qq.com'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱 message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8') message['From'] = Header("菜鸟教程", 'utf-8') message['To'] = Header("测试", 'utf-8') subject = 'Python SMTP 邮件测试' message['Subject'] = Header(subject, 'utf-8') try: smtpObj = smtplib.SMTP() smtpObj.connect(mail_host, 25) # 25 为 SMTP 端口号 smtpObj.login(mail_user,mail_pass) smtpObj.sendmail(sender, receivers, message.as_string()) print "邮件发送成功" except smtplib.SMTPException: print "Error: 无法发送邮件" 发送HTML格式的邮件 !/usr/bin/python -- coding: UTF-8 -- import smtplib from email.mime.text import MIMEText from email.header import Header sender = 'from@runoob.com' receivers = ['429240967@qq.com'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱 mail_msg = """ <p>Python 邮件发送测试...</p> <p><a href="http://www.runoob.com">这是一个链接</a></p> """ message = MIMEText(mail_msg, 'html', 'utf-8') message['From'] = Header("菜鸟教程", 'utf-8') message['To'] = Header("测试", 'utf-8') subject = 'Python SMTP 邮件测试' message['Subject'] = Header(subject, 'utf-8') try: smtpObj = smtplib.SMTP('localhost') smtpObj.sendmail(sender, receivers, message.as_string()) print "邮件发送成功" except smtplib.SMTPException: print "Error: 无法发送邮件" 发送带附件的邮件: !/usr/bin/python -- coding: UTF-8 -- import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.header import Header sender = 'from@runoob.com' receivers = ['429240967@qq.com'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱 创建一个带附件的实例 message = MIMEMultipart() message['From'] = Header("菜鸟教程", 'utf-8') message['To'] = Header("测试", 'utf-8') subject = 'Python SMTP 邮件测试' message['Subject'] = Header(subject, 'utf-8') 邮件正文内容 message.attach(MIMEText('这是菜鸟教程Python 邮件发送测试……', 'plain', 'utf-8')) 构造附件1,传送当前目录下的 test.txt 文件 att1 = MIMEText(open('test.txt', 'rb').read(), 'base64', 'utf-8') att1["Content-Type"] = 'application/octet-stream' 这里的filename可以任意写,写什么名字,邮件中显示什么名字 att1["Content-Disposition"] = 'attachment; filename="test.txt"' message.attach(att1) 构造附件2,传送当前目录下的 runoob.txt 文件 att2 = MIMEText(open('runoob.txt', 'rb').read(), 'base64', 'utf-8') att2["Content-Type"] = 'application/octet-stream' att2["Content-Disposition"] = 'attachment; filename="runoob.txt"' message.attach(att2) try: smtpObj = smtplib.SMTP('localhost') smtpObj.sendmail(sender, receivers, message.as_string()) print "邮件发送成功" except smtplib.SMTPException: print "Error: 无法发送邮件" 在HTML中添加图片 !/usr/bin/python -- coding: UTF-8 -- import smtplib from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.header import Header sender = 'from@runoob.com' receivers = ['429240967@qq.com'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱 msgRoot = MIMEMultipart('related') msgRoot['From'] = Header("菜鸟教程", 'utf-8') msgRoot['To'] = Header("测试", 'utf-8') subject = 'Python SMTP 邮件测试' msgRoot['Subject'] = Header(subject, 'utf-8') msgAlternative = MIMEMultipart('alternative') msgRoot.attach(msgAlternative) mail_msg = """ <p>Python 邮件发送测试...</p> <p><a href="http://www.runoob.com">菜鸟教程链接</a></p> <p>图片演示:</p> <p><img src="cid:image1"></p> """ msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8')) 指定图片为当前目录 fp = open('test.png', 'rb') msgImage = MIMEImage(fp.read()) fp.close() 定义图片 ID,在 HTML 文本中引用 msgImage.add_header('Content-ID', '<image1>') msgRoot.attach(msgImage) try: smtpObj = smtplib.SMTP('localhost') smtpObj.sendmail(sender, receivers, msgRoot.as_string()) print "邮件发送成功" except smtplib.SMTPException: print "Error: 无法发送邮件" 发送QQ邮件: !/usr/bin/python -- coding: UTF-8 -- import smtplib from email.mime.text import MIMEText from email.utils import formataddr my_sender='429240967@qq.com' # 发件人邮箱账号 my_pass = 'xxxxxxxxxx' # 发件人邮箱密码 my_user='429240967@qq.com' # 收件人邮箱账号,我这边发送给自己 def mail(): ret=True try: msg=MIMEText('填写邮件内容','plain','utf-8') msg['From']=formataddr(["FromRunoob",my_sender]) # 括号里的对应发件人邮箱昵称、发件人邮箱账号 msg['To']=formataddr(["FK",my_user]) # 括号里的对应收件人邮箱昵称、收件人邮箱账号 msg['Subject']="菜鸟教程发送邮件测试" # 邮件的主题,也可以说是标题 server=smtplib.SMTP_SSL("smtp.qq.com", 465) # 发件人邮箱中的SMTP服务器,端口是25 server.login(my_sender, my_pass) # 括号中对应的是发件人邮箱账号、邮箱密码 server.sendmail(my_sender,[my_user,],msg.as_string()) # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件 server.quit() # 关闭连接 except Exception: # 如果 try 中的语句没有执行,则会执行下面的 ret=False ret=False return ret ret=mail() if ret: print("邮件发送成功") else: print("邮件发送失败") thread.start_new_thread !/usr/bin/python -- coding: UTF-8 -- import thread import time 为线程定义一个函数 def print_time( threadName, delay): count = 0 while count < 5: time.sleep(delay) count += 1 print "%s: %s" % ( threadName, time.ctime(time.time()) ) 创建两个线程 try: thread.start_new_thread( print_time, ("Thread-1", 2, ) ) thread.start_new_thread( print_time, ("Thread-2", 4, ) ) except: print "Error: unable to start thread" while 1: pass xml解析 tkinter

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

python——高级特性

切片操作符 Python提供了切片(Slice)操作符,切片操作十分有用,可以通过切片轻松取出某一段数列。比如前10个数: #slice切片操作符 取前10个元素 L=list(range(0,100)) print(L[:10])#索引为0可以省略 》[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] L[0:10]表示从索引0开始取(索引为0可以省略),直到索引10为止(但是不包括索引10),就是一个“左闭右开”区间[0,10),切片操作符也可以取倒数元素比如L[-2:-1]取到倒数第二个元素98。 用切片操作符实现strip的默认方法 #str.strip() 去掉首尾的指定字符(字符串),默认为空格 str=' hello world! ' print(str.strip()) #使用[:]切片操作符去掉字符串首尾空格 n=0 j=0#前索引 k=0#后索引 while n<len(str): if str[n:n+1]!=' ': j=n break n=n+1 while n<len(str): if str[-n-1:-n]!=' ': k=-n break n=n+1 print(str[j:k]) 》hello world! 》hello world! 进阶版 使用[:]切片操作符实现strip方法 #使用[:]切片操作符实现strip方法 def my_strip(str,chr=' '): n=0#循环索引重置 J=0#前索引 K=0#后索引 Ls=len(str)#输入字符串长度 L=len(chr)#去掉字符长度 #得到前索引J while n<Ls: if str[n:n+L]!=chr: J=n break n=n+L n=0#循环索引重置 #得到后索引K while n<Ls: if str[-n-L:Ls-n]!=chr: K=Ls-n break n=n+L #返回切片 return str[J:K] str='0000a000' chr='000' print(my_strip(str,chr)) 》0a 简单版 看了一个老哥的代码,非常简单,佩服,记录如下: def trim(str,chr=' '): L=len(chr) while str[:L] == chr: #如果字符串第一个是空格,删除第一个 str = str[L:] while str[-L:] == chr: #如果字符串最后一个是空格,删除最后一个 str = str[:-L] return str

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

Hive高级优化

并发执行 job1: a join b aa job2: c join d cc job3: aa join cc 说明: job1和job2可以并行执行。 JVM重用 它是对map/reduce 运行的任务,一个jvm可以运行多个map 任务。小数据可以使用jvm重用。性能可以提升70% Reduce的数据 默认reduce的任务是一个,可以根据自己的业务进行手动调整,不断测试把它调节到一个合适的值。 推测执行 说明:MapReduce调优,默认启用的,最后把它关闭掉,这只为false。场景:运行reduce时,有的慢,有的快,applicationMaster在另外一个机器上启动一个一模一样的reduce,那个先完成用那个。 Map数据 说明:依照块的大小来

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

ContextMenu高级用法

关键字: ContextMenu ##背景 我们经常在列表的页面中,点击列表中的行,一般进入详情页面,长按列表中一行,会弹出一个菜单,包含了对某一行的操作(编辑、删除等等),也知道通常的用法: - 0x01. 在Activity中注册需要上下文菜单的View: `registerForContextMenu(mListView);` - 0x02. 然后在Activity中继承onCreateContextMenu方法,添加菜单项: ``` @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { Log.d(LOG_TAG, "onCreateContextMenu"); super.onCreateContextMenu(menu, v, menuInfo); menu.setHeaderTitle(R.string.prompt); menu.add(Menu.NONE, R.id.context_menu_item_delete_record, Menu.NONE, R.string.delete_record);//groupId, itemId, order, title menu.add(Menu.NONE, R.id.context_menu_item_delete_record_with_file, Menu.NONE, R.string.delete_record_with_file); }``` **PS:每次长按出现上下文菜单都会调用这个方法** ``` /** * Called when a context menu for the {@code view} is about to be shown. * Unlike {@link #onCreateOptionsMenu(Menu)}, this will be called every * time the context menu is about to be shown and should be populated for * the view (or item inside the view for {@link AdapterView} subclasses, * this can be found in the {@code menuInfo})). * <p> * Use {@link #onContextItemSelected(android.view.MenuItem)} to know when an * item has been selected. * <p> * It is not safe to hold onto the context menu after this method returns. * */ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { } ``` - 0x03. 接下来长按列表中一行的时候,会弹出上下文菜单: ![device-2015-11-04-141103.png](http://upload-images.jianshu.io/upload_images/728306-c1f997a517d009c7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) - 0x04. 点击菜单后,在Activity中继承onContextItemSelected方法进行处理: ``` @Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()){ } } ``` - 0x05. 获取Item标识(id) 我们删除数据库或者一行记录的时候,要知道主键(一般是id)才能进行操作,很多人就想办法,有的是把ListView的每个ItemView添加一个LongClickListener,然后长按的时候记录下Position,然后在进行相应处理。 其实有更优雅的做法,onContextItemSelected(MenuItem item)回调的参数item可以获取item.getMenuInfo(),在ListView和Adapter的模式中,可以强制转换成AdapterContextMenuInfo,拿到targetView(即所长按行的ItemVew,如果我们需要什么参数,直接放到View.setTag中去即可): ``` AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); int index = info.position; View view = info.targetView; ``` 至此,常见的用法就完了,那么遇到其他自定义View呢? - 0x06. 自定义View的ContextMenu实现 下面以用到的RecycleView为例,没有了ListView及其Adapter的封装,我们需要自己处理ContextMenu。 最重要的是继承View的两个方法: 1.上下文菜单Item的附加信息(上面item.getMenuInfo()); ``` /** * Views should implement this if they have extra information to associate * with the context menu. The return result is supplied as a parameter to * the {@link OnCreateContextMenuListener#onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} * callback. * * @return Extra information about the item for which the context menu * should be shown. This information will vary across different * subclasses of View. */ protected ContextMenuInfo getContextMenuInfo() { return null; } ``` 2.ViewGroup的showContextMenuForChild,每次弹出上下文菜单都会调用此方法,需要在这里更新ContextMenuInfo; ``` /** * {@inheritDoc} */ public boolean showContextMenuForChild(View originalView) { return mParent != null && mParent.showContextMenuForChild(originalView); } ``` - 0x07. 自定义RecycleView的ContextMenu全部代码 ``` package com.lbrant.phone.view; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.util.Log; import android.view.ContextMenu; import android.view.View; /** * 作者:dell * 时间:2015/11/3 18:34 * 文件:PhoneRecorder * 描述: */ public class ContextMenuRecyclerView extends RecyclerView { private static final String LOG_TAG = "ContextMenuRecyclerView"; private RecyclerContextMenuInfo mContextMenuInfo = new RecyclerContextMenuInfo(); public ContextMenuRecyclerView(Context context) { super(context); } public ContextMenuRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); } public ContextMenuRecyclerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected ContextMenu.ContextMenuInfo getContextMenuInfo() { return mContextMenuInfo; } @Override public boolean showContextMenuForChild(View originalView) { Log.d(LOG_TAG, "showContextMenuForChild"); Object tag = originalView.getTag(); if (tag instanceof RecyclerItemMarker) { mContextMenuInfo.mRecycleItemMarker = (RecyclerItemMarker) tag; } return super.showContextMenuForChild(originalView); } public static class RecyclerItemMarker { public final int position; public final Object obj; public RecyclerItemMarker(int position, Object obj) { this.position = position; this.obj = obj; } } public static class RecyclerContextMenuInfo implements ContextMenu.ContextMenuInfo { public RecyclerItemMarker mRecycleItemMarker; } } private class RecordRecycleViewAdapter extends RecyclerView.Adapter<RecordRecycleViewAdapter.RecordViewHolder> { private Cursor mCallRecordCursor; private int mIdIndex; private int mPhoneNumberIndex; private int mCallTimeIndex; private int mDurationIndex; private int mPathIndex; public RecordRecycleViewAdapter(Cursor cursor) { mCallRecordCursor = cursor; updateCursorColumnIndex(); } private void updateCursorColumnIndex() { if (mCallRecordCursor != null) { mIdIndex = mCallRecordCursor.getColumnIndex(BaseDatabaseHelper.RECORDS_COLUMNS._ID); mPhoneNumberIndex = mCallRecordCursor.getColumnIndex(BaseDatabaseHelper.RECORDS_COLUMNS.NUMBER); mCallTimeIndex = mCallRecordCursor.getColumnIndex(BaseDatabaseHelper.RECORDS_COLUMNS.CALL_TIME); mDurationIndex = mCallRecordCursor.getColumnIndex(BaseDatabaseHelper.RECORDS_COLUMNS.DURATION); mPathIndex = mCallRecordCursor.getColumnIndex(BaseDatabaseHelper.RECORDS_COLUMNS.PATH); } } @Override public RecordRecycleViewAdapter.RecordViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View contentView = LayoutInflater.from(parent.getContext()).inflate(R.layout.record_list_item, parent, false); RecordViewHolder viewHolder = new RecordViewHolder(contentView); return viewHolder; } @Override public void onBindViewHolder(RecordRecycleViewAdapter.RecordViewHolder holder, final int position) { holder.itemView.setLongClickable(true); if (mCallRecordCursor != null && mCallRecordCursor.moveToPosition(position)) { long id = mCallRecordCursor.getLong(mIdIndex); String phoneNumber = mCallRecordCursor.getString(mPhoneNumberIndex); long seconds = mCallRecordCursor.getLong(mDurationIndex); String callTime = mCallRecordCursor.getString(mCallTimeIndex); String path = mCallRecordCursor.getString(mPathIndex); String duration = String.format("%1$02d:%2$02d:%3$02d", seconds / 3600, seconds % 3600 / 60, seconds % 60); RecordInfo info = new RecordInfo(); info.setId(id); info.setPhoneNumber(phoneNumber); info.setSecondsDuration(seconds); info.setCallTime(callTime); info.setPath(path); holder.itemView.setTag(new ContextMenuRecyclerView.RecyclerItemMarker(position, info)); holder.mTextViewPhoneNumber.setText(phoneNumber); holder.mTextViewDuration.setText(duration); holder.mTextviewCallTime.setText(callTime); Cursor cursor = queryContactByPhoneNumber(ContactsContract.CommonDataKinds.Phone.NUMBER + " = '" + phoneNumber + "'"); if (cursor != null) { if (cursor.moveToNext()) { long contactId = cursor.getInt(0); Cursor contactCursor = queryContact(ContactsContract.Contacts._ID + "=" + contactId); if (contactCursor != null) { holder.mTextViewName.setText(contactCursor.getString(1)); contactCursor.close(); } } cursor.close(); } } } @Override public void onViewRecycled(RecordViewHolder holder) { super.onViewRecycled(holder); holder.itemView.setOnCreateContextMenuListener(null); } @Override public int getItemCount() { return mCallRecordCursor == null ? 0 : mCallRecordCursor.getCount(); } public void changeCursor(Cursor cursor) { if (cursor != mCallRecordCursor) { if (mCallRecordCursor != null) { mCallRecordCursor.close(); } mCallRecordCursor = cursor; updateCursorColumnIndex(); notifyDataSetChanged(); } } public class RecordViewHolder extends RecyclerView.ViewHolder { private ImageView mImageViewAvatar; private TextView mTextViewPhoneNumber; private TextView mTextViewName; private TextView mTextviewCallTime; private TextView mTextViewDuration; public RecordViewHolder(View itemView) { super(itemView); mImageViewAvatar = (ImageView) itemView.findViewById(R.id.imageViewAvatar); mTextViewName = (TextView) itemView.findViewById(R.id.textViewName); mTextViewPhoneNumber = (TextView) itemView.findViewById(R.id.textViewPhoneNumber); mTextviewCallTime = (TextView) itemView.findViewById(R.id.textViewCallTime); mTextViewDuration = (TextView) itemView.findViewById(R.id.textViewDuration); } } } ``` **有两个地方需要注意:** 1.onBindViewHolder中给ItemView添加Tag; 2.设置ItemView的LongClickable为true,不然不会出现上下文菜单(具体原因见ContextMenu原理分析); holder.itemView.setLongClickable(true); 本文转自 breezy_yuan 51CTO博客,原文链接:http://blog.51cto.com/lbrant/1709643,如需转载请自行联系原作者

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

yum 高级用法

1, yum 安装文件,并下载RPM 包 yum reinstall openstack-nova-* --downloadonly --downloaddir=/opt/ yum reinstall xxxxx --downloadonly --downloaddir=. 2, 同步 RPM 包到本地 wget -m -c -np --reject=html,gif,A,D -nH --cut-dirs=4 -P ar/wwwml/openstack-havana/http://repos.fedorapeople.org/repos/openstack/openstack-havana/epel-6/ 3, yum -y update 错误解决办法 warning:rpmts_HdrFromFdno:HeaderV3RSA/SHA256Signature,keyID0608b895:NOKEY Retrievingkeyfromfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 GPGkeyretrievalfailed:[Errno14]Couldnotopen/readfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 解决办法: rpm-Uvhhttp://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm [root@master ~]# rpm -e --nodeps mysql-server 在 mysqld 服务中读取信息时出错:没有那个文件或目录 error: %preun(mysql-server-5.1.73-3.el6_5.x86_64) scriptlet failed, exit status 1 解决办法: [root@master /]# rpm -e --noscripts mysql-server [root@master /]# rpm -qa|grep mysql 如何实现,yum group 安装Linux开发工具 1 yumgroupinstall "DevelopmentTools" "DevelopmentLibraries" 本文转自 swq499809608 51CTO博客,原文链接:http://blog.51cto.com/swq499809608/1410994

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

MapReduce高级特性

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1010885678/article/details/51366342 计数器 因为计数器的查看往往比查看集群日志来的方便快捷 所以有些情况下计数器信息比集群日志更加有效 用户自定义的计数器 关于Hadoop的内置计数器的介绍可以参考Hadoop权威指南第九章MapReduce Features中的Build-in Counts小节 这里限于篇幅不再说明 MapReduce允许用户在程序中使用枚举或者字符串的格式类自定义计数器 一个作业可以定义的计数器不限,使用枚举类型时 枚举类型的名称即为组名,枚举类型的字段即为计数器名 计数器是全局的,会跨越所有Mapper和Reducer进行使用,并在作业结束的时候产生一个结果 例如,现有枚举类型如下: enum Temperature{ MISSING, MALFORMAT } 在MapReduce程序中可以这样来使用计数器: context.getCounter(Temperature.MISSING).increment(1); context.getCounter(Temperature.MALFORMAT).increment(1); 动态计数器 由于枚举类型在编译的时候就确定了所有字段,但是某些情况下我们可能要根据未知的名称来命名计数器 这个时候就可以使用动态计数器来实现: context.getCounter("计数器组名","计数器名").increment(1); 这里的计数器名的获得方式可以是任意的,例如动态获取的字段值等 但是大部分情况下,枚举类型可以足够使用了,而且枚举类型阅读性较强,易于使用,而且是类型安全的 所以推荐尽可能的使用枚举类型 在代码中获取计数器的值 除了通过Web UI、CLI和-counter参数获得作业的计数器,用户也可以通过代码在程序中获取计数器的值: String jobId = args[0]; Cluster cluster = new Cluster(getConf()); Job job = cluster.getJob(JobId.forName(jobId)); if(job == null){ System.err.println("No job whih ID %s found",jobId); return -1; } if(!job.isComplete()){ System.err.println("Job %s is not complete",jobId); return -1; } Counters counters = job.getCounters(); //关键代码 long missing = conters.findCounter(Temperature.MISSING).getValue(); long total = counters.findCounter(TaskCounter.MAP_INPUT_RECORDS).getValue(); 排序 部分排序 部分排序是指在map阶段,对每个分区中的数据进行排序的过程 在Hadoop提交作业自定义排序和分组中可以看到 MapReduce中控制部分排序的方法不只有一种,控制排序的顺序如下: 1.如果设置了mapreduce.job.output.key.comparator.class属性或者setComparatorClass()方法,则使用设置的类进行部分排序 2.否则,键必须是WritableComparable的子类,并使用针对该键类型的已经注册的comparator 3.否则,使用RawComparator将字节流反序列化为对象,并调用WritableComparable的comparaTo()方法 我们在自定义数据类型的时候继承自WritableComparable,并重写了comparaTo方法,这里的设置是最后才会使用的 如果定义了RawComparator/WritableComparator的具体实现类,那么将会优先使用这个设置,因为其可以直接对比字节流数组 全排序 MapReduce Shuffle阶段的排序只针对各个单独的分区,也就是之前讨论到的部分排序 对于每个分区,其数据是有序的,但是从数据的总体来看,是无序的 如何让MapReduce产生全局有序的数据呢? 最简单的办法是只使用一个分区,但是这就丧失了MapReduce并行计算的特性,必须在单台机器上处理所有数据 事实上,除了使用一个分区,还有另外一种方式既可以实现全局有序,也可以充分利用到MapReduce的并行计算能力 但是这个方法需要做一些额外的工作 思考一下,在部分排序中,每个分区内的数据都是有序的,但是从分区的角度看就是无序的了 如果我们能够确保分区也是有序的呢?,例如分区1保存1-100的数据,分区2保存101-200的数据,一次类推 那么从分区的角度看,各个分区之间是有序的,而分区内部的数据也是自然有序的 从而就做到了数据的全局有序 但是在这个过程中需要注意一个情况:如何确保每个分区的数据量分配是均匀的? 因为在实际场景中,1-100中包含的数据可能有1000个,而101-200的数据只有50个,这就造成了数据倾斜的问题 为了解决这个问题,我们通常需要深入的了解数据的组成特性 但是在海量数据的情况下,不可能对全部数据进行检查 这时我们可以使用采样的方式来进行 采样的核心思想是只查看一小部分的键,获得键的近似分布由此构建分区 Hadoop中已经内置了若干的采样器,接口如下: public interface Sampler<K,V>{ K[] getSample(InputFormat<K,V> inf,Job job) throw IOException,InterruptedException; } 但是通常不会直接使用这个getSample接口,而是由InputSampler的writePartitionFile方法调用 目的是创建一个SequenceFile来存储定义分区的键 public static <K,V> writePartitionFile(Job job,Sampler<K,V> sampler) throw IOException,ClassNotFoundException,InterruptedException 该SequenceFile会被TotalOrderPartitioner使用来为作业创建分区: //设置分区类为TotalOrderPartitioner job.setPartitionerClass(TotalOrderPartitioner.class); //使用随机采样器,采样率为0.1,最大样本数和最大分区数为10000何10,任意一个条件满足之后即刻停止采样 InputSampler.Sampler<IntWritable,Text> sampler = new InputSampler.RandomSampler<IntWritable,Text>(0.1,10000,10); //使用该采样器创建定义分区键的SequenceFile InputSampler.writePartitionFile(job,sampler); ///获得该SequenceFile并加入分布式缓存中共享 String partitionFile = TotalOrderPartitioner.getPartitionFile(conf); URI uri = new URI(partitionFile); jov.addCacheFile(uri); 这个采样器将会运行在客户端,所以会从集群上下载数据,需要注意下载的数据量不要太大不然运行时间很久 使用该方法还可以自由的设置reducer的任务数,即分区数,通过mapreduce.job.reducers来设置最后需要产生多少个均匀的分区 RandomSampler是一种比较通用的采样器,除了它,还有另外一些例如: SplitSampler:只采样一个分片中的前n条记录,没有从全部分片中广泛采样,所以不适合已经排好序的数据 IntervalSampler:以一定的间隔从分片中选择键,因此很适合排过序的数据 二次排序 二次排序即为对数据的值进行排序,其实在Hadoop I/O的序列化小节中 就已经讨论过这个问题了,具体案例可以参考:Hadoop提交作业自定义排序和分组 Join连接 使用MapReduce进行连接操作的方式和技巧取决于数据集的规模和结构 如果一个数据集很大,另外一个很小,完全可以使用MapReduce中的DistributedCache 将小数据集分发到各个节点上 如果两个数据集都很大,那么又可以分为Map端的Join和Reduce端的Join Map端的Join Map端的Join操作会在数据到达map函数之前执行 为了达到这个目的,Map端的输入数据必须: 1.两个数据集被划分为数量相同的分区 2.两个数据集按照相同的键进行排序 由于Map可以设置之前执行的多个作业的输出为其输入,按照以上条件 此时输入数据应该满足: 1.两个作业有相同的reduce数量 2.键是相同的且不可分割 满足Map端Join操作的要求之后,可以利用org.apache.hadoop.mapreduce.join包中的ComsiteInputFormat类在map函数之前执行join操作 Reduce端的Join 比起Map端,Reduce端的Join对数据的要求没有那么高,利用Shuffle相同键的记录会被输入到同一个reducer(分区)中的特性 Reducer端可以天然进行Join操作,但是由于数据要经过Shuffle过程,所以效率往往比Map端的Join要低 而且在Reduce端的Join中,还可以利用到之前讨论的二次排序 有时候join连接需要一个数据集先于另一个数据集到达reduce函数,这时候我们可以听过二次排序对数据的值做一个标号 先要达到的数据标号设置为0,另外一个数据集设置为1,然后根据这个标号进行排序就可以实现让想要的数据集先一步到达reduce 边数据分布 所谓的边数据(Side Data)可以理解为MapReduce作业执行过程中 所有任务都有可能要使用到的只读的的数据,用以辅助处理主数据 使用JobConfiguration Configuration类的各种setter方法可以方便的设置一些键值对类型的数据 用户可以通过getConfiguration方法获得配置的信息 这种方式足以应对很多只需要设置一些属性的场合 但是其缺点是: 只适合类似属性设置的小数据 对于很复杂的对象,用户需要自己设置序列化和反序列化 每次读取配置的时候所有设置都将读取内存,不管有没有用到 DistributedCache 分布式缓存机制在作业运行之前将用户设置的数据拷贝到各个节点中以供使用 缓存的容量大小默认为10G,可以通过yarn.nodemanager.localizer.cache.target-size-mb来配置(以字节为单位) 具体的使用方式参考:MapReduce中的DistributedCache 作者:@小黑

资源下载

更多资源
Mario

Mario

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

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文件系统,支持十年生命周期更新。

WebStorm

WebStorm

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

用户登录
用户注册