Python - - 模块 - - 常用模块

目录

  • re模块
  • collections模块
  • 时间模块
  • random模块
  • os模块
  • sys模块
  • 序列化模块
  • hashlib模块
  • configparse模块
  • logging模块

1 re模块

1.1 根据手机号码一共11位并且是只以13、14、15、18开头的数字这些特点,用python获取:

  • str 方法获取
while True:
    phone_number = input('please input your phone number : ')
    if len(phone_number) == 11 \
            and phone_number.isdigit()\
            and (phone_number.startswith('13') \
            or phone_number.startswith('14') \
            or phone_number.startswith('15') \
            or phone_number.startswith('18')):
        print('是合法的手机号码')
    else:
        print('不是合法的手机号码')
  • re 模块获取
import re
phone_number = input('please input your phone number : ')
if re.match('^(13|14|15|18)[0-9]{9}$',phone_number):
        print('是合法的手机号码')
else:
        print('不是合法的手机号码')

1.2 re模块下的常用方法

findall

  • 返回所有满足匹配条件的结果,放在列表里
import re

ret = re.findall('[a-z]', 'eva egon yuan')  # 
print(ret) 
# 结果呈现
['eva', 'egon', 'yuan']
  • findall的优先级查询:
import re

ret = re.findall('www.(baidu|abc).com', 'www.baidu.com')
print(ret)          # ['baidu']     这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可

ret = re.findall('www.(?:baidu|abc).com', 'www.baidu.com')
print(ret)  # ['www.baidu.com']

# 结果呈现
['baidu']
['www.baidu.com']
  • 找整个字符串,遇到匹配上的就返回,遇不到就None
  • 如果有返回值 ret.group() 就可以取到值
  • 取分组中的内容:ret.group(1)
import re

# ret = re.search('a', 'eva egon yuan').group()
ret = re.search('a', 'eva egon yuan')
print(ret)
print(ret.group())
# 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
# 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回报错。
# 结果呈现

a


import re
ret = re.search('a', 'eva egon yuan')
if ret:
    print(ret.group())
# 结果呈现
a


# 从分组中取值,根据组的顺序取值
import re
ret = re.search("\d(\w)+", "awirs198723jsdc")
print(ret.group())
print(ret.group(1))
# 从分组中取值,根据组的名字取值  ?P
import re
ret = re.search("\d(?P\w)+", "awirs198723jsdc")
print(ret.group())
print(ret.group("name"))

# 结果呈现
198723jsdc
c

match

  • 是从头开始匹配,如果正则规则从头开始匹配上,就返回一个变量,则返回None
  • 匹配的内容需要用group才能显示,如果字符串没有匹配,且报错。
import re

# ret = re.match('a', 'eva egon yuan').group()
ret = re.match('a', 'eva egon yuan')
if ret:
    print(ret.group())
# 结果呈现


ret = re.match('a', 'eva egon yuan')
if ret:
    print(ret.group())
# 结果呈现
ev

split

  • 分割
import re

ret = re.split('[ab]', 'abcd')  # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
print(ret) 

# 结果呈现
['', '', 'cd']
  • split的优先级查询
    • 在匹配部分加上()之后所切出的结果是不同的,
    • 没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项,
    • 这个在某些需要保留匹配部分的使用过程是非常重要的。
ret=re.split("\d+","eva3egon4yuan")
print(ret) #结果 : ['eva', 'egon', 'yuan']

ret=re.split("(\d+)","eva3egon4yuan")
print(ret) #结果 : ['eva', '3', 'egon', '4', 'yuan']

# 结果呈现
['eva', 'egon', 'yuan']
['eva', '3', 'egon', '4', 'yuan']

sub

  • 替换
import re

ret = re.sub('\d', 'H', 'eva3egon4yuan4', 1) # 将数字替换成'H',参数1表示只替换1个,不写参数1则替换所有数字
print(ret)

# 结果呈现
evaHegon4yuan4

subn

  • 替换
import re

ret = re.subn('\d', 'H', 'eva3egon4yuan4')#将数字替换成'H',返回元组(替换的结果,替换了多少次)
print(ret)

# 结果呈现
('evaHegonHyuanH', 3)

compile

  • compile 编译:正则表达式很长且要多长使用
import re

obj = re.compile('\d{3}')  # 将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
print(ret.group())  

# 结果呈现
123

finditer

  • 返回迭代器
import re

ret = re.finditer('\d', 'ds3sy4784a')   #finditer返回一个存放匹配结果的迭代器
print(ret)  # 
print(next(ret).group())  #查看第一个结果
print(next(ret).group())  #查看第二个结果
print([i.group() for i in ret])  #查看剩余的左右结果

# 结果呈现

3
4
['7', '8', '4']

1.2.1 匹配标签

import re


ret = re.search("<(?P\w+)>\w+","

hello

") # 还可以在分组中利用?的形式给分组起名字 # 获取的匹配结果可以直接用group('名字')拿到对应的值 print(ret.group('tag_name')) print(ret.group()) # 结果呈现 h1

hello

ret = re.search(r"<(\w+)>\w+","

hello

") # 如果不给组起名字,也可以用\序号来找到对应的组,表示要找的内容和前面的组内容一致 # 获取的匹配结果可以直接用group(序号)拿到对应的值 print(ret.group(1)) print(ret.group()) # 结果呈现 h1

hello

1.2.2 匹配整数

import re

ret=re.findall(r"\d+","1-2*(60+(-40.35/5)-(-4*3))")
print(ret) 

# 结果呈现
['1', '2', '60', '40', '35', '5', '4', '3']


ret=re.findall(r"\d+\.\d+|(\d+)","1-2*(60+(-40.35/5)-(-4*3))")
print(ret) #['1', '2', '60', '40', '35', '5', '4', '3']
ret.remove("")
print(ret)

# 结果呈现
['1', '-2', '60', '', '5', '-4', '3']
['1', '-2', '60', '5', '-4', '3']


ret=re.findall(r"-?\d+\.\d*|(-?\d+)","1-2*(60+(-40.35/5)-(-4*3))")
print(ret) 
ret.remove("")
print(ret) 

# 结果呈现
['1', '-2', '60', '', '5', '-4', '3']
['1', '-2', '60', '5', '-4', '3']

1.2.3 数字匹配

1、 匹配一段文本中的每行的邮箱
      http://blog.csdn.net/make164492212/article/details/51656638

2、 匹配一段文本中的每行的时间字符串,比如:‘1990-07-12’;

   分别取出1年的12个月(^(0?[1-9]|1[0-2])$)、
   一个月的31天:^((0?[1-9])|((1|2)[0-9])|30|31)$

3、 匹配qq号。(腾讯QQ号从10000开始)  [1,9][0,9]{4,}

4、 匹配一个浮点数。       ^(-?\d+)(\.\d+)?$   或者  -?\d+\.?\d*

5、 匹配汉字。             ^[\u4e00-\u9fa5]{0,}$ 

6、 匹配出所有整数

1.2.4 爬虫练习

  • 使用正则 compile
import requests

import re
import json

def getPage(url):

    response=requests.get(url)
    return response.text

def parsePage(s):
    
    com=re.compile('
.*?
.*?(?P\d+).*?(?P.*?)</span>' '.*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)评价</span>',re.S) ret=com.finditer(s) for i in ret: yield { "id":i.group("id"), "title":i.group("title"), "rating_num":i.group("rating_num"), "comment_num":i.group("comment_num"), } def main(num): url='https://movie.douban.com/top250?start=%s&filter='%num response_html=getPage(url) ret=parsePage(response_html) print(ret) f=open("move_info7","a",encoding="utf8") for obj in ret: print(obj) data=json.dumps(obj,ensure_ascii=False) f.write(data+"\n") if __name__ == '__main__': count=0 for i in range(10): main(count) count+=25</code></pre> <ul> <li>简化版</li> </ul> <pre><code>import re import json from urllib.request import urlopen def getPage(url): response = urlopen(url) return response.read().decode('utf-8') def parsePage(s): com = re.compile( '<div class="item">.*?<div class="pic">.*?<em .*?>(?P<id>\d+).*?<span class="title">(?P<title>.*?)</span>' '.*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)评价</span>', re.S) ret = com.finditer(s) for i in ret: yield { "id": i.group("id"), "title": i.group("title"), "rating_num": i.group("rating_num"), "comment_num": i.group("comment_num"), } def main(num): url = 'https://movie.douban.com/top250?start=%s&filter=' % num response_html = getPage(url) ret = parsePage(response_html) print(ret) f = open("move_info7", "a", encoding="utf8") for obj in ret: print(obj) data = str(obj) f.write(data + "\n") count = 0 for i in range(10): main(count) count += 25</code></pre> <ul> <li>正则 findall</li> </ul> <pre><code>import re import json from urllib.request import urlopen def getPage(url): response = urlopen(url) return response.read().decode('utf-8') def parsePage(s): ret = re.findall( '<div class="item">.*?<div class="pic">.*?<em .*?>(?P<id>\d+).*?<span class="title">(?P<title>.*?)</span>' '.*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)评价</span>', s, re.S) return ret def main(num): url = 'https://movie.douban.com/top250?start=%s&filter=' % num response_html = getPage(url) ret = parsePage(response_html) print(ret) count = 0 for i in range(10): main(count) count += 25 # url 从网页上把代码爬下来 # bytes decode - - 》 utf-8 网页内容就是待匹配字符串 # ret = re.findall(正则,带匹配的字符串) # ret 是所有匹配到的内容组成的列表</code></pre> <ul> <li>flag</li> </ul> <pre><code>flags有很多可选值: re.I(IGNORECASE)忽略大小写,括号内是完整的写法 re.M(MULTILINE)多行模式,改变^和$的行为 re.S(DOTALL)点可以匹配任意字符,包括换行符 re.L(LOCALE)做本地化识别的匹配,表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境,不推荐使用 re.U(UNICODE) 使用\w \W \s \S \d \D使用取决于unicode定义的字符属性。在python3中默认使用该flag re.X(VERBOSE)冗长模式,该模式下pattern字符串可以是多行的,忽略空白字符,并可以添加注释</code></pre> <h2 id="collections模块">2 collections模块</h2> <ul> <li>python 中的扩展数据类型</li> <li>在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。 <ul> <li>1.namedtuple: 生成可以使用名字来访问元素内容的tuple</li> <li>2.deque: 双端队列,可以快速的从另外一侧追加和推出对象</li> <li>3.Counter: 计数器,主要用来计数</li> <li>4.OrderedDict: 有序字典</li> <li>5.defaultdict: 带有默认值的字典</li> </ul></li> </ul> <h3 id="namedtuple">2.1 namedtuple</h3> <ul> <li>tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成,但是看到(1, 2),很难看出这个tuple是用来表示一个坐标的。</li> </ul> <pre><code>p = (1, 2)</code></pre> <ul> <li>namedtuple就派上了用场:</li> </ul> <pre><code>from collections import namedtuple Point = namedtuple("point", ["x", "y", "z"]) p1 = Point(1, 2, 3) p2 = Point(3, 2, 1) print(p1.x) print(p1.y) print(p1, p2) # 结果呈现 1 2 point(x=1, y=2, z=3) point(x=3, y=2, z=1)</code></pre> <pre><code># 花色和数字 Card = namedtuple("card", ["suits", "number"]) c1 = Card("红桃", 2) print(c1) print(c1.number) print(c1.suits) # 结果呈现 card(suits='红桃', number=2) 2 红桃</code></pre> <ul> <li>类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义:</li> </ul> <pre><code># namedtuple('名称', [属性list]): Circle = namedtuple('Circle', ['x', 'y', 'r'])</code></pre> <h3 id="deque-双端队列">2.2 deque 双端队列</h3> <ul> <li>使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。</li> </ul> <pre><code># 队列 先进先出 FIFO import queue q = queue.Queue() q.put(10) q.put(5) q.put(6) print(q) print("队列个数 %d" % q.qsize()) print(q.get()) print(q.get()) print(q.get()) print(q.get()) # 阻塞 # 等待新输入的值 # 执行结果 <queue.Queue object at 0x0000007147F4E278> 队列个数 3 10 5 6</code></pre> <ul> <li>deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:</li> </ul> <pre><code>from collections import deque dq = deque([1, 2]) dq.append("a") # 从后面放数据[3, 1, 2, "a"] dq.appendleft("b") # 从前面放数据["b",1, 2, "a"] dq.insert(1, 3) # 从指定的索引位置插入数据["b", 3, 1, 2, "a"] print(dq.pop()) # 从前面放数据 print(dq.popleft()) # 从前面放数据 print(dq) # 结果呈现 a b deque([3, 1, 2])</code></pre> <ul> <li>deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。</li> </ul> <h3 id="ordereddict">2.3 OrderedDict</h3> <ul> <li>使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。</li> <li>如果要保持Key的顺序,可以用OrderedDict:</li> </ul> <pre><code>from collections import OrderedDict d = dict([('a', 1), ('b', 2), ('c', 3)]) print(d) # dict的Key是无序的字典 od = OrderedDict([('a', 1), ('b', 2), ('c', 3)]) print(od) # OrderedDict的Key是有序的字典 print("*" * 50) for k in od: print(k) # 结果呈现 {'a': 1, 'b': 2, 'c': 3} OrderedDict([('a', 1), ('b', 2), ('c', 3)]) ************************************************** a b c</code></pre> <ul> <li>注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:</li> </ul> <pre><code>from collections import OrderedDict od = OrderedDict() od['z'] = 1 od['y'] = 2 od['x'] = 3 print(od.keys()) # 按照插入的Key的顺序返回 # 结果呈现 odict_keys(['z', 'y', 'x'])</code></pre> <h3 id="defaultdict">2.4 defaultdict</h3> <ul> <li>有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。</li> <li>即: {'k1': 大于66 , 'k2': 小于66}</li> </ul> <h4 id="原生字典解决方法">原生字典解决方法</h4> <pre><code>values = [11, 22, 33,44,55,66,77,88,99,90] my_dict = {} for value in values: if value>66: if my_dict.__contains__('k1'): my_dict['k1'].append(value) else: my_dict['k1'] = [value] else: if my_dict.__contains__('k2'): my_dict['k2'].append(value) else: my_dict['k2'] = [value] print(my_dict) # 结果呈现 {'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99, 90]}</code></pre> <h4 id="defaultdict-字典解决方法">defaultdict 字典解决方法</h4> <pre><code>from collections import defaultdict values = [11, 22, 33,44,55,66,77,88,99,90] my_dict = defaultdict(list) for value in values: if value>66: my_dict['k1'].append(value) else: my_dict['k2'].append(value) print(my_dict) # 结果呈现 defaultdict(<class 'list'>, {'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99, 90]})</code></pre> <ul> <li>使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict:</li> </ul> <pre><code>from collections import defaultdict dd = defaultdict(lambda: 'N/A') dd['key1'] = 'abc' print(dd['key1']) # key1存在 print(dd['key2']) # key2不存在,返回默认值 # 结果呈现 abc N/A</code></pre> <h3 id="counter">2.5 Counter</h3> <ul> <li>Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。</li> </ul> <pre><code>from collections import Counter c = Counter('abcdeabcdabcaba') print(c) # 结果呈现 Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})</code></pre> <h4 id="创建">2.5.1 创建</h4> <ul> <li>下面的代码说明了Counter类创建的四种方法:</li> </ul> <pre><code># Counter类的创建 >>> c = Counter() # 创建一个空的Counter类 >>> c = Counter('gallahad') # 从一个可iterable对象(list、tuple、dict、字符串等)创建 >>> c = Counter({'a': 4, 'b': 2}) # 从一个字典对象创建 >>> c = Counter(a=4, b=2) # 从一组键值对创建</code></pre> <ul> <li>计数值的访问与缺失的键</li> <li>当所访问的键不存在时,返回0,而不是KeyError;否则返回它的计数。</li> </ul> <h4 id="计数值的访问">2.5.2 计数值的访问</h4> <pre><code>>>> c = Counter("abcdefgab") >>> c["a"] 2 >>> c["c"] 1 >>> c["h"] 0</code></pre> <h4 id="计数器的更新update和subtract">2.5.3 计数器的更新(update和subtract)</h4> <ul> <li>可以使用一个iterable对象或者另一个Counter对象来更新键值。</li> <li>计数器的更新包括增加和减少两种。其中,增加使用update()方法:</li> <li>计数器的更新(update)</li> </ul> <pre><code>>>> c = Counter('which') >>> c.update('witch') # 使用另一个iterable对象更新 >>> c['h'] 3 >>> d = Counter('watch') >>> c.update(d) # 使用另一个Counter对象更新 >>> c['h'] 4</code></pre> <ul> <li>减少则使用subtract()方法:</li> <li>计数器的更新(subtract)</li> </ul> <pre><code>>>> c = Counter('which') >>> c.subtract('witch') # 使用另一个iterable对象更新 >>> c['h'] 1 >>> d = Counter('watch') >>> c.subtract(d) # 使用另一个Counter对象更新 >>> c['a'] -1</code></pre> <h4 id="键的修改和删除">2.5.4 键的修改和删除</h4> <ul> <li>当计数值为0时,并不意味着元素被删除,删除元素应当使用del。</li> <li>键的删除</li> </ul> <pre><code>>>> c = Counter("abcdcba") >>> c Counter({'a': 2, 'c': 2, 'b': 2, 'd': 1}) >>> c["b"] = 0 >>> c Counter({'a': 2, 'c': 2, 'd': 1, 'b': 0}) >>> del c["a"] >>> c Counter({'c': 2, 'b': 2, 'd': 1})</code></pre> <h4 id="elements">2.5.5 elements()</h4> <ul> <li>返回一个迭代器。元素被重复了多少次,在该迭代器中就包含多少个该元素。元素排列无确定顺序,个数小于1的元素不被包含。</li> <li>elements()方法</li> </ul> <pre><code>>>> c = Counter(a=4, b=2, c=0, d=-2) >>> list(c.elements()) ['a', 'a', 'a', 'a', 'b', 'b']</code></pre> <h4 id="most_commonn">2.5.6 most_common([n])</h4> <ul> <li>返回一个TopN列表。如果n没有被指定,则返回所有元素。当多个元素计数值相同时,排列是无确定顺序的。</li> <li>most_common()方法</li> </ul> <pre><code>>>> c = Counter('abracadabra') >>> c.most_common() [('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)] >>> c.most_common(3) [('a', 5), ('r', 2), ('b', 2)] </code></pre> <h4 id="浅拷贝copy">2.5.7 浅拷贝copy</h4> <pre><code>>>> c = Counter("abcdcba") >>> c Counter({'a': 2, 'c': 2, 'b': 2, 'd': 1}) >>> d = c.copy() >>> d Counter({'a': 2, 'c': 2, 'b': 2, 'd': 1})</code></pre> <h4 id="算术和集合操作">2.5.8 算术和集合操作</h4> <ul> <li>+、-、&、|操作也可以用于Counter。其中&和|操作分别返回两个Counter对象各元素的最小值和最大值。需要注意的是,得到的Counter对象将删除小于1的元素。</li> <li>Counter对象的算术和集合操作</li> </ul> <pre><code>>>> c = Counter(a=3, b=1) >>> d = Counter(a=1, b=2) >>> c + d # c[x] + d[x] Counter({'a': 4, 'b': 3}) >>> c - d # subtract(只保留正数计数的元素) Counter({'a': 2}) >>> c & d # 交集: min(c[x], d[x]) Counter({'a': 1, 'b': 1}) >>> c | d # 并集: max(c[x], d[x]) Counter({'a': 3, 'b': 2})</code></pre> <h4 id="其他常用操作">2.5.9 其他常用操作</h4> <ul> <li>下面是一些Counter类的常用操作,来源于Python官方文档</li> </ul> <h4 id="counter类常用操作">Counter类常用操作</h4> <pre><code>sum(c.values()) # 所有计数的总数 c.clear() # 重置Counter对象,注意不是删除 list(c) # 将c中的键转为列表 set(c) # 将c中的键转为set dict(c) # 将c中的键值对转为字典 c.items() # 转为(elem, cnt)格式的列表 Counter(dict(list_of_pairs)) # 从(elem, cnt)格式的列表转换为Counter类对象 c.most_common()[:-n:-1] # 取出计数最少的n个元素 c += Counter() # 移除0和负值</code></pre> <h2 id="time模块">3 time模块</h2> <ul> <li>时间模块</li> <li>和时间有关系的我们就要用到时间模块。在使用模块之前,应该首先导入这个模块。</li> </ul> <pre><code>import time #常用方法 time.sleep(secs) # (线程)推迟指定的时间运行。单位为秒。 time.time() # 获取当前时间戳</code></pre> <h3 id="表示时间的三种方式">3.1 表示时间的三种方式</h3> <ul> <li>在Python中,通常有这三种方式来表示时间:时间戳、元组(struct_time)、格式化的时间字符串:</li> <li>1, 时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。</li> <li>2, 格式化的时间字符串(Format String): ‘1999-12-06’</li> </ul> <h4 id="python中时间日期格式化符号">python中时间日期格式化符号:</h4> <pre><code>%y 两位数的年份表示(00-99) %Y 四位数的年份表示(000-9999) %m 月份(01-12) %d 月内中的一天(0-31) %H 24小时制小时数(0-23) %I 12小时制小时数(01-12) %M 分钟数(00=59) %S 秒(00-59) %f 毫秒(000000-999999) %a 本地简化星期名称 %A 本地完整星期名称 %b 本地简化的月份名称 %B 本地完整的月份名称 %c 本地相应的日期表示和时间表示 %F 本地年月日的日期表示 %j 年内的一天(001-366) %p 本地A.M.或P.M.的等价符 %U 一年中的星期数(00-53)星期天为星期的开始 %w 星期(0-6),星期天为星期的开始 %W 一年中的星期数(00-53)星期一为星期的开始 %x 本地相应的日期表示 %X 本地相应的时间表示 %Z 当前时区的名称 %% %号本身 </code></pre> <ul> <li>3,元组(struct_time) :struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)</li> </ul> <table> <thead> <tr class="header"> <th style="text-align:left;">索引(Index)</th> <th style="text-align:left;">属性(Attribute) 值(Values)</th> <th style="text-align:left;"></th> </tr> </thead> <tbody> <tr class="odd"> <td style="text-align:left;">0</td> <td style="text-align:left;">tm_year(年)</td> <td style="text-align:left;">比如2011</td> </tr> <tr class="even"> <td style="text-align:left;">1</td> <td style="text-align:left;">tm_mon(月)</td> <td style="text-align:left;">1 - 12</td> </tr> <tr class="odd"> <td style="text-align:left;">2</td> <td style="text-align:left;">tm_mday(日)</td> <td style="text-align:left;">1 - 31</td> </tr> <tr class="even"> <td style="text-align:left;">3</td> <td style="text-align:left;">tm_hour(时)</td> <td style="text-align:left;">0 - 23</td> </tr> <tr class="odd"> <td style="text-align:left;">4</td> <td style="text-align:left;">tm_min(分)</td> <td style="text-align:left;">0 - 59</td> </tr> <tr class="even"> <td style="text-align:left;">5</td> <td style="text-align:left;">tm_sec(秒)</td> <td style="text-align:left;">0 - 60</td> </tr> <tr class="odd"> <td style="text-align:left;">6</td> <td style="text-align:left;">tm_wday(weekday)</td> <td style="text-align:left;">0 - 6(0表示周一)</td> </tr> <tr class="even"> <td style="text-align:left;">7</td> <td style="text-align:left;">tm_yday(一年中的第几天)</td> <td style="text-align:left;">1 - 366</td> </tr> <tr class="odd"> <td style="text-align:left;">8</td> <td style="text-align:left;">tm_isdst(是否是夏令时)</td> <td style="text-align:left;">默认为0</td> </tr> </tbody> </table> <h3 id="python中表示时间的几种格式">3.2 python中表示时间的几种格式</h3> <pre><code># 格式化时间 - - 字符串:人类可读性 # 时间戳时间 - - float时间: 计算机看的 # 结构话时间 - - 元组:计算机用的 import time # 时间戳 print(time.time()) # 结果呈现 # 时间字符串 print(time.strftime("%F %X")) print(time.strftime("%Y-%m-%d %H:%M:%S")) # year month day HOUR MINUTE SECOND # 结果呈现 2018-09-29 10:34:52 2018-09-29 10:34:52 # 时间元组:localtime将一个时间戳转换为当前时区的struct_time print(time.localtime()) print(time.localtime().tm_year) # 结果呈现 time.struct_time(tm_year=2018, tm_mon=9, tm_mday=29, tm_hour=10, tm_min=34, tm_sec=52, tm_wday=5, tm_yday=272, tm_isdst=0) 2018</code></pre> <ul> <li>小结:时间戳是计算机能够识别的时间;时间字符串是人能够看懂的时间;元组则是用来操作时间的</li> </ul> <h3 id="几种格式之间的转换">3.3 几种格式之间的转换</h3> <p><a href="http://img.e-com-net.com/image/info8/e0713e1e32d943e781a907d342691b36.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/e0713e1e32d943e781a907d342691b36.jpg" alt="Python - - 模块 - - 常用模块_第1张图片" width="399" height="203" style="border:1px solid black;"></a></p> <pre><code># 时间戳-->结构化时间 # time.gmtime(时间戳) # UTC时间,与英国伦敦当地时间一致 # time.localtime(时间戳) # 当地时间。例如我们现在在北京执行这个方法:与UTC时间相差8小时,UTC时间+8小时 = 北京时间 >>>time.gmtime(1500000000) time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=2, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0) >>>time.localtime(1500000000) time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=10, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0) # 结构化时间-->时间戳  # time.mktime(结构化时间) >>>time_tuple = time.localtime(1500000000) >>>time.mktime(time_tuple) 1500000000.0</code></pre> <pre><code># 结构化时间-->字符串时间 # time.strftime("格式定义","结构化时间") 结构化时间参数若不传,则显示当前时间 >>>time.strftime("%Y-%m-%d %X") '2017-07-24 14:55:36' >>>time.strftime("%Y-%m-%d",time.localtime(1500000000)) '2017-07-14' # 字符串时间-->结构化时间 # time.strptime(时间字符串,字符串对应格式) >>>time.strptime("2017-03-16","%Y-%m-%d") time.struct_time(tm_year=2017, tm_mon=3, tm_mday=16, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=75, tm_isdst=-1) >>>time.strptime("07/24/2017","%m/%d/%Y") time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=205, tm_isdst=-1)</code></pre> <p><a href="http://img.e-com-net.com/image/info8/5759c32754dd44c4b461ff3f4fb9b364.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/5759c32754dd44c4b461ff3f4fb9b364.jpg" alt="Python - - 模块 - - 常用模块_第2张图片" width="408" height="202" style="border:1px solid black;"></a></p> <pre><code># 结构化时间 --> %a %b %d %H:%M:%S %Y串 # time.asctime(结构化时间) 如果不传参数,直接返回当前时间的格式化串 >>>time.asctime(time.localtime(1500000000)) 'Fri Jul 14 10:40:00 2017' >>>time.asctime() 'Mon Jul 24 15:18:33 2017' # 时间戳 --> %a %b %d %H:%M:%S %Y串 # time.ctime(时间戳) 如果不传参数,直接返回当前时间的格式化串 >>>time.ctime() 'Mon Jul 24 15:19:07 2017' >>>time.ctime(1500000000) 'Fri Jul 14 10:40:00 2017' </code></pre> <h3 id="计算时间差">3.4 计算时间差</h3> <pre><code>import time true_time=time.mktime(time.strptime('2018-09-29 08:30:00','%Y-%m-%d %H:%M:%S')) time_now=time.mktime(time.strptime('2018-09-30 17:30:00','%Y-%m-%d %H:%M:%S')) dif_time=time_now-true_time struct_time=time.gmtime(dif_time) print('过去了%d年%d月%d天%d小时%d分钟%d秒'%(struct_time.tm_year-1970,struct_time.tm_mon-1, struct_time.tm_mday-1,struct_time.tm_hour, struct_time.tm_min,struct_time.tm_sec)) # 结果呈现 过去了0年0月1天9小时0分钟0秒</code></pre> <h2 id="random模块">4 random模块</h2> <ul> <li>随机数模块</li> </ul> <pre><code>>>> import random # 随机小数 >>> random.random() # 大于0且小于1之间的小数 0.7664338663654585 >>> random.uniform(1,3) # 大于1小于3的小数 1.6270147180533838 # 随机整数 >>> random.randint(1,5) # 大于等于1且小于等于5之间的整数 >>> random.randrange(1,10,2) # 大于等于1且小于10之间的奇数 # 随机选择一个返回 >>> random.choice([1,'23',[4,5]]) #1或者23或者[4,5] # 随机选择多个返回,返回的个数为函数的第二个参数 >>> random.sample([1,'23',[4,5]],2) # 列表元素任意2个组合 [[4, 5], '23'] # 打乱列表顺序 >>> item=[1,3,5,7,9] >>> random.shuffle(item) # 打乱次序 >>> item [5, 1, 3, 7, 9] >>> random.shuffle(item) >>> item [5, 9, 7, 1, 3]</code></pre> <h3 id="生成随机验证码">4.1 生成随机验证码</h3> <pre><code>import random def v_code(): code = '' for i in range(5): num=random.randint(0,9) alf=chr(random.randint(65,90)) add=random.choice([num,alf]) code="".join([code,str(add)]) return code print(v_code()) # 结果呈现 W31PA</code></pre> <h2 id="os模块">5 os模块</h2> <ul> <li>与操作系统交互的模块, os模块是与操作系统交互的一个接口</li> </ul> <pre><code>os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 os.remove() 删除一个文件 os.rename("oldname","newname") 重命名文件/目录 os.stat('path/filename') 获取文件/目录信息 os.system("bash command") 运行shell命令,直接显示 os.popen("bash command).read() 运行shell命令,获取执行结果 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd os.path os.path.abspath(path) 返回path规范化的绝对路径 os.path.split(path) 将path分割成目录和文件名二元组返回 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素 os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False os.path.isabs(path) 如果path是绝对路径,返回True os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 os.path.getatime(path) 返回path所指向的文件或者目录的最后访问时间 os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间 os.path.getsize(path) 返回path的大小</code></pre> <ul> <li><strong>注意</strong>:os.stat('path/filename') 获取文件/目录信息 的结构说明</li> </ul> <h4 id="stat-结构">stat 结构</h4> <pre><code>stat 结构: st_mode: inode 保护模式 st_ino: inode 节点号。 st_dev: inode 驻留的设备。 st_nlink: inode 的链接数。 st_uid: 所有者的用户ID。 st_gid: 所有者的组ID。 st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。 st_atime: 上次访问的时间。 st_mtime: 最后一次修改的时间。 st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)。</code></pre> <h4 id="os模块的属性">os模块的属性</h4> <pre><code>os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/" os.linesep 输出当前平台使用的行终止符,win下为"\r\n",Linux下为"\n" os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为: os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'</code></pre> <h2 id="sys模块">6 sys模块</h2> <ul> <li>sys模块是与python解释器交互的一个接口</li> </ul> <pre><code>sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0),错误退出sys.exit(1) sys.version 获取Python解释程序的版本信息 sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform 返回操作系统平台名称</code></pre> <h4 id="异常处理和status">异常处理和status</h4> <pre><code>import sys try: sys.exit(1) except SystemExit as e: print(e) # 结果呈现 1</code></pre> <h2 id="序列化模块">7 序列化模块</h2> <ul> <li>从原本的 <strong>字典、列表</strong> 等 <strong>数据类型</strong> 内容转换成一个 <strong>字符串</strong> 的 <strong>过程</strong> 就叫做 <strong>序列化</strong>。</li> <li>从 <strong>字符串</strong> 转换成 原本的 <strong>字典、列表</strong> 等的 <strong>数据类型</strong> 的 <strong>过程</strong> 就叫做 <strong>反序列化</strong>。</li> </ul> <h3 id="为什么要有序列化模块">7.1 为什么要有序列化模块</h3> <pre><code>,将字典转换成一个字符串很简单,就是str(dic)就可以办到了,为什么我们还要学习序列化模块呢? 没错序列化的过程就是从dic 变成str(dic)的过程。现在你可以通过str(dic),将一个名为dic的字典转换成一个字符串, 但是你要怎么把一个字符串转换成字典呢? 聪明的你肯定想到了eval(),如果我们将一个字符串类型的字典str_dic传给eval,就会得到一个返回的字典类型了。 eval()函数十分强大,但是eval是做什么的?e官方demo解释为:将字符串str当成有效的表达式来求值并返回计算结果。 BUT!强大的函数有代价。安全性是其最大的缺点。 想象一下,如果我们从文件中读出的不是一个数据结构,而是一句"删除文件"类似的破坏性语句,那么后果实在不堪设设想。 而使用eval就要担这个风险。 所以,我们并不推荐用eval方法来进行反序列化操作(将str转换成python中的数据结构)</code></pre> <h3 id="序列化的目的">7.2 序列化的目的</h3> <ul> <li>1、以某种存储形式使自定义对象持久化;</li> <li>2、将对象从一个地方传递到另一个地方。</li> <li>3、使程序更具维护性。</li> </ul> <p><a href="http://img.e-com-net.com/image/info8/7c63804b71c54028939cd146d44f4c7a.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/7c63804b71c54028939cd146d44f4c7a.jpg" alt="Python - - 模块 - - 常用模块_第3张图片" width="480" height="127" style="border:1px solid black;"></a></p> <h3 id="json">7.3 json</h3> <ul> <li>通用的序列化格式</li> <li>只有很少的一部分数据类型能够通过jsonz转化成字符串</li> <li>Json模块提供了四个功能:dumps、dump、loads、load</li> </ul> <h4 id="dumps-序列化方法-loads-反序列化方法">7.3.1 dumps 序列化方法 loads 反序列化方法</h4> <ul> <li>所有的操作都在内存中</li> </ul> <pre><code>dic = {"k1":"v1", 1: "a"} print(type(dic),dic) import json str_d = json.dumps(dic) # 序列化:将一个字典转换成一个字符串 print(type(str_d), str_d) # 注意,json转换完的字符串类型的字典中的字符串是由""表示的 dic_d = json.loads(str_d) # 反序列化:将一个字符串格式的字典转换成一个字典 print(type(dic_d), dic_d) # 注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示 # 结果呈现 <class 'dict'> {'k1': 'v1', 1: 'a'} <class 'str'> {"k1": "v1", "1": "a"} <class 'dict'> {'k1': 'v1', '1': 'a'}</code></pre> <pre><code>import json list_dic = [1,['a','b','c'],3,{'k1':'v1','k2':'v2'}] str_dic = json.dumps(list_dic) # 也可以处理嵌套的数据类型 print(type(str_dic),str_dic) list_dic2 = json.loads(str_dic) print(type(list_dic2),list_dic2) # 结果呈现 <class 'str'> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}] <class 'list'> [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}] </code></pre> <h4 id="json-dump-load">7.3.2 json dump load</h4> <ul> <li>所有的操作都在磁盘上的文件中</li> </ul> <pre><code>import json dic = {"k1":"v1", 1: "a"} f = open("xlh_file", "w", encoding="utf-8") json.dump(dic, f) # dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件 f.close() f = open("xlh_file", "r", encoding="utf-8") res = json.load(f) # load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回 f.close print(type(res), res) # xlh_file 文件 {"k1": "v1", "1": "a"} # 结果呈现 <class 'dict'> {'k1': 'v1', '1': 'a'}</code></pre> <h4 id="ensure_ascii关键字参数">7.3.3 ensure_ascii关键字参数</h4> <pre><code>import json dic = {"k1":"北京", 1: "a"} f = open("xlh_file", "w", encoding="utf-8") json.dump(dic, f,ensure_ascii=False) f.close() f = open("xlh_file", "r", encoding="utf-8") res = json.load(f) f.close print(type(res), res) # 未使用了参数 ensure_ascii 文件 xlh_file 内容如下 {"k1": "\u5317\u4eac", "1": "a"} # 使用了参数 ensure_ascii 文件 xlh_file 内容如下 {"k1": "北京", "1": "a"} # 结果呈现 <class 'dict'> {'k1': '北京', '1': 'a'}</code></pre> <h4 id="json-使用for-间接分部">7.3.4 json 使用for 间接分部</h4> <pre><code>import json lst = [{"k1": "v1"},{"k2": "v2"},{"k3": "v3"} ] f = open("xlh_file_1", "w") for dic in lst: str_dic = json.dumps(dic) f.write(str_dic + "\n") f.close() f = open("xlh_file_1", "r") lit = [] for line in f: dic = json.loads(line.strip()) lit.append(dic) f.close() print(lit) # 文件 xlh_file_1 {"k1": "v1"} {"k2": "v2"} {"k3": "v3"} # 结果呈现 [{'k1': 'v1'}, {'k2': 'v2'}, {'k3': 'v3'}]</code></pre> <h4 id="其它参数说明">7.3.5 其它参数说明</h4> <pre><code>Serialize obj to a JSON formatted str.(字符串表示的json对象) Skipkeys:默认值是False,如果dict的keys内的数据不是python的基本类型(str,unicode,int,long,float,bool,None),设置为False时,就会报TypeError的错误。此时设置成True,则会跳过这类key ensure_ascii:,当它为True的时候,所有非ASCII码字符显示为\uXXXX序列,只需在dump时将ensure_ascii设置为False即可,此时存入json的中文即可正常显示。) If check_circular is false, then the circular reference check for container types will be skipped and a circular reference will result in an OverflowError (or worse). If allow_nan is false, then it will be a ValueError to serialize out of range float values (nan, inf, -inf) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (NaN, Infinity, -Infinity). indent:应该是一个非负的整型,如果是0就是顶格分行显示,如果为空就是一行最紧凑显示,否则会换行且按照indent的数值显示前面的空白分行显示,这样打印出来的json数据也叫pretty-printed json separators:分隔符,实际上是(item_separator, dict_separator)的一个元组,默认的就是(‘,’,’:’);这表示dictionary内keys之间用“,”隔开,而KEY和value之间用“:”隔开。 default(obj) is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. sort_keys:将数据根据keys的值进行排序。 To use a custom JSONEncoder subclass (e.g. one that overrides the .default() method to serialize additional types), specify it with the cls kwarg; otherwise JSONEncoder is used.</code></pre> <h4 id="json-格式化输出">7.3.6 json 格式化输出</h4> <pre><code>import json data = {'username':['李华','二愣子'],'sex':'male','age':16} json_dic2 = json.dumps(data,sort_keys=True,indent=2,separators=(',',':'),ensure_ascii=False) print(json_dic2) # 结果呈现 { "age":16, "sex":"male", "username":[ "李华", "二愣子" ] }</code></pre> <h3 id="pickle">7.4 pickle</h3> <ul> <li>所有的python中的数据类型都可以转化成字符串形式</li> <li>pickle序列化的内容只有python能理解</li> <li>且部分反序列化依赖python代码</li> <li>pickle 使用方法与 json 一样,pickle 序列化的为 bytes 类型,读写文件必须加 <code>"b"</code></li> </ul> <pre><code>import pickle dic = {'k1':'v1','k2':'v2','k3':'v3'} str_dic = pickle.dumps(dic) print(str_dic) #一串二进制内容 dic2 = pickle.loads(str_dic) print(dic2) #字典 # 结果呈现 b'\x80\x03}q\x00(X\x02\x00\x00\x00k1q\x01X\x02\x00\x00\x00v1q\x02X\x02\x00\x00\x00k2q\x03X\x02\x00\x00\x00v2q\x04X\x02\x00\x00\x00k3q\x05X\x02\x00\x00\x00v3q\x06u.' {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}</code></pre> <pre><code>import pickle import time struct_time = time.localtime(1000000000) print(struct_time) f = open('pickle_file','wb') pickle.dump(struct_time,f) f.close() f = open('pickle_file','rb') struct_time2 = pickle.load(f) print(struct_time2.tm_year) # 结果呈现 time.struct_time(tm_year=2001, tm_mon=9, tm_mday=9, tm_hour=9, tm_min=46, tm_sec=40, tm_wday=6, tm_yday=252, tm_isdst=0) 2001</code></pre> <h4 id="pickle-可以直接分部">7.4.1 pickle 可以直接分部</h4> <pre><code>import pickle import time struct_time1 = time.localtime(1000000000) struct_time2 = time.localtime(2000000000) f = open('pickle_file','wb') pickle.dump(struct_time1,f) pickle.dump(struct_time2,f) f.close() f = open('pickle_file','rb') struct_time1 = pickle.load(f) struct_time2 = pickle.load(f) print(struct_time1.tm_year) print(struct_time2.tm_year) # 文件 pickle_file �ctime struct_time q (M�K K K K.K(KK�K tq}q(X tm_zoneqX ?D1¨²¡À¨º¡Á?¨º¡À??qX tm_gmtoffqM�pu�qRq.�ctime struct_time q (M�KKKK!KKK�K tq}q(X tm_zoneqX ?D1¨²¡À¨º¡Á?¨º¡À??qX tm_gmtoffqM�pu�qRq. # 结果呈现 2001 2033</code></pre> <h3 id="shelve">7.5 shelve</h3> <ul> <li>序列化句柄</li> <li>使用句柄直接操作,非常方便</li> <li>shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式,是pickle 更上一层的封装。</li> <li>Shelve模块提供了基本的存储操作,Shelve中的open函数在调用的时候返回一个shelf对象,通过该对象可以存储内容,即像操作字典一样进行存储操作。当在该对象中查找元素时,对象会根据已经存储的版本进行重新构建,当给某个键赋值的时候,元素会被存储。</li> </ul> <h4 id="持久化存储">持久化存储</h4> <pre><code>import shelve def member_info(name, age): print('Member info:', name, age) name = ['Jack', 'Pumpkin', 'Tom'] info = {'name': 'Pumpkin', 'age': 20} with shelve.open('shelve_demo') as data: data['name'] = name data['info'] = info data['func'] = member_info # shelve 会生成三个文件 # shelve_demo.bak 'name', (0, 43) 'info', (512, 45) 'func', (1024, 27) # shelve_demo.dat �]q (X JackqX PumpkinqX Tomqe. �}q (X nameqX PumpkinqX ageqKu. �c__main__ member_info q . # shelve_demo.dir 'name', (0, 43) 'info', (512, 45) 'func', (1024, 27)</code></pre> <h4 id="解析文件内容">解析文件内容</h4> <pre><code>import shelve def member_info(name, age): print('Member info:', name, age) with shelve.open('shelve_demo') as data: print(data['name']) print(data['info']) print(data['func']('Alex', 22)) # 结果呈现 ['Jack', 'Pumpkin', 'Tom'] {'name': 'Pumpkin', 'age': 20} Member info: Alex 22 None</code></pre> <h4 id="value值的修改">value值的修改</h4> <ul> <li>一般情况下,通过shelve来open一个对象后,只能进行一次赋值处理,赋值后不能再次更新处理</li> </ul> <pre><code> import shelve def member_info(name, age): print("Member info:", name, age) name = ['Jack', 'Pumpkin', 'Tom'] info = {'name':'Pumpkin', 'age':18} with shelve.open('shelve_demo') as data: data['name'] = name data['info'] = info data['name'].append('Alex') print(data['name']) # 结果呈现 ['Jack', 'Pumpkin', 'Tom'] # 第一次赋值后apend的元素并没有生效</code></pre> <ul> <li>再次open打开结果也是这样:</li> </ul> <pre><code>import shelve def member_info(name, age): print("Member info:", name, age) name = ['Jack', 'Pumpkin', 'Tom'] info = {'name':'Pumpkin', 'age':18} with shelve.open('shelve_demo') as data: print(data['name']) # 结果呈现 ['Jack', 'Pumpkin', 'Tom']</code></pre> <ul> <li>方法一: shelve open一个对象后,先用临时变量指向对象副本,在临时变量上修改后让对象副本再次指向临时变量,从而覆盖保存对象副本。这种方法的本质是对open后的对象重新赋新值,并非在原有基础上进行update,也就是open后的对象内存指向地址发生了变化。</li> </ul> <pre><code>import shelve def member_info(name, age): print("Member info:", name, age) name = ['Jack', 'Pumpkin', 'Tom'] info = {'name':'Pumpkin', 'age':18} with shelve.open('shelve_demo') as data: data['name'] = name data['info'] = info temp = data['name'] # 这里的关键点在于对临时变量的使用 temp.append('Alex') data['name'] = temp print(data['name']) # 结果呈现 ['Jack', 'Pumpkin', 'Tom', 'Alex']</code></pre> <ul> <li>方法二:借助open的writeback=True参数来实现,默认情况下该参数的值为False。</li> </ul> <pre><code>import shelve def member_info(name, age): print("Member info:", name, age) name = ['Jack', 'Pumpkin', 'Tom'] info = {'name':'Pumpkin', 'age':18} with shelve.open('shelve_demo', writeback=True) as data: data['name'] = name data['info'] = info data['name'].append('Alex') print(data['name']) # 结果呈现 ['Jack', 'Pumpkin', 'Tom', 'Alex']</code></pre> <ul> <li>value值的更新还有一个update方法,使用起来也比较方便:</li> </ul> <pre><code>import shelve def member_info(name, age): print("Member info:", name, age) name = ['Jack', 'Pumpkin', 'Tom'] info = {'name':'Pumpkin', 'age':18} with shelve.open('shelve_demo', writeback=True) as data: data['name'] = name data['info'] = info data.update({'name':['Jack', 'Pumpkin', 'Tom', 'Alex']}) # 这里也是重新赋值 print(data['name']) # 结果呈现 ['Jack', 'Pumpkin', 'Tom', 'Alex']</code></pre> <ul> <li>load 方法看结果</li> </ul> <pre><code>import shelve def member_info(name, age): print("Member info:", name, age) name = ['Jack', 'Pumpkin', 'Tom'] info = {'name':'Pumpkin', 'age':18} with shelve.open('shelve_demo') as data: print(data['name']) # 结果呈现 ['Jack', 'Pumpkin', 'Tom', 'Alex']</code></pre> <ul> <li>get方法</li> <li>通过shelve.open反序列化load对象到内存后,可以通过get方法来获取key对应的value:</li> </ul> <pre><code>import shelve def member_info(name, age): print("Member info:", name, age) name = ['Jack', 'Pumpkin', 'Tom'] info = {'name':'Pumpkin', 'age':18} with shelve.open('shelve_demo') as data: print(data.get('name')) # 结果呈现 ['Jack', 'Pumpkin', 'Tom', 'Alex']</code></pre> <h4 id="shelve概念总结">shelve概念总结:</h4> <ul> <li>shelve模块可以看做是pickle模块的升级版,因为shelve使用的就是pickle的序列化协议,但是shelve比pickle提供的操作方式更加简单、方便;</li> <li>shelve模块相对于其它两个模块在将Python数据持久化到本地磁盘时有一个很明显的优点就是,它允许我们可以像操作dict一样操作被序列化的数据,而不必一次性的保存或读取所有数据。</li> <li>shelve模块持久化支持更多的python数据类型。</li> </ul> <h3 id="序列化小结">7.6 序列化小结:</h3> <ul> <li>1、需要与外部系统交互时用json模块;</li> <li>2、需要将少量、简单Python数据持久化到本地磁盘文件时可以考虑用pickle模块;</li> <li><p>3、需要将大量Python数据持久化到本地磁盘文件或需要一些简单的类似数据库的增删改查功能时,可以考虑用shelve模块。</p></li> <li>序列化模块 <ul> <li>数据类型转化成字符串的过程就是序列化</li> <li>字符串转化成数据类型的过程就是反序列化</li> <li>为了方便存储和网络传输</li> <li>json <ul> <li>dumps</li> <li>loads</li> <li>dump 和文件有关</li> <li>load 不能load多次</li> </ul></li> <li>pickle <ul> <li>方法和json一样</li> <li>dump 和 load 的时候, 文件是 rb 或者 wb 打开的</li> <li>支持 python 所有的数据类型</li> <li>序列化和反序列化需要相同的环境</li> </ul></li> <li>shelve <ul> <li>open 方法</li> <li>open方法获取一个文件句柄</li> <li>操作和字典类似</li> </ul></li> </ul></li> </ul> <h2 id="hashlib模块">8 hashlib模块</h2> <h3 id="算法介绍">8.1 算法介绍</h3> <ul> <li>Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等。</li> <li>什么是摘要算法呢?摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。</li> <li>摘要算法就是通过摘要函数f()对任意长度的数据data计算出固定长度的摘要digest,目的是为了发现原始数据是否被人篡改过。</li> <li>摘要算法之所以能指出数据是否被篡改过,就是因为摘要函数是一个单向函数,计算f(data)很容易,但通过digest反推data却非常困难。而且,对原始数据做一个bit的修改,都会导致计算出的摘要完全不同。</li> <li>我们以常见的摘要算法MD5为例,计算出一个字符串的MD5值:</li> </ul> <pre><code>import hashlib md5 = hashlib.md5() md5.update('how to use md5 in python hashlib?') print md5.hexdigest() # 结果呈现 d26a53750bc40b38b65a520292f69306</code></pre> <ul> <li>如果数据量很大,可以分块多次调用update(),最后计算的结果是一样的:</li> </ul> <pre><code>md5 = hashlib.md5() md5.update('how to use md5 in ') md5.update('python hashlib?') print md5.hexdigest()</code></pre> <ul> <li>MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。另一种常见的摘要算法是SHA1,调用SHA1和调用MD5完全类似:</li> </ul> <pre><code>import hashlib sha1 = hashlib.sha1() sha1.update('how to use sha1 in ') sha1.update('python hashlib?') print sha1.hexdigest()</code></pre> <ul> <li>SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示。比SHA1更安全的算法是SHA256和SHA512,不过越安全的算法越慢,而且摘要长度更长。</li> </ul> <h3 id="摘要算法应用">8.2 摘要算法应用</h3> <ul> <li>任何允许用户登录的网站都会存储用户登录的用户名和口令。如何存储用户名和口令呢?方法是存到数据库表中:</li> </ul> <pre><code>name | password --------+---------- michael | 123456 bob | abc999 alice | alice2008</code></pre> <ul> <li>如果以明文保存用户口令,如果数据库泄露,所有用户的口令就落入黑客的手里。此外,网站运维人员是可以访问数据库的,也就是能获取到所有用户的口令。正确的保存口令的方式是不存储用户的明文口令,而是存储用户口令的摘要,比如MD5:</li> </ul> <pre><code>username | password ---------+--------------------------------- michael | e10adc3949ba59abbe56e057f20f883e bob | 878ef96e86145580c38c87f0410ad153 alice | 99b1c2188db85afee403b1536010c2c9</code></pre> <ul> <li>考虑这么个情况,很多用户喜欢用123456,888888,password这些简单的口令,于是,黑客可以事先计算出这些常用口令的MD5值,得到一个反推表:</li> </ul> <pre><code>'e10adc3949ba59abbe56e057f20f883e': '123456' '21218cca77804d2ba1922c33e0151105': '888888' '5f4dcc3b5aa765d61d8327deb882cf99': 'password'</code></pre> <ul> <li>这样,无需破解,只需要对比数据库的MD5,黑客就获得了使用常用口令的用户账号。</li> <li>对于用户来讲,当然不要使用过于简单的口令。但是,我们能否在程序设计上对简单口令加强保护呢?</li> <li>由于常用口令的MD5值很容易被计算出来,所以,要确保存储的用户口令不是那些已经被计算出来的常用口令的MD5,这一方法通过对原始口令加一个复杂字符串来实现,俗称“加盐”:</li> </ul> <pre><code>hashlib.md5("salt".encode("utf8"))</code></pre> <ul> <li>经过Salt处理的MD5口令,只要Salt不被黑客知道,即使用户输入简单口令,也很难通过MD5反推明文口令。</li> </ul> <pre><code>import hashlib # 提供摘要算法的模块 md5 = hashlib.md5() md5.update(b"min123") print(md5.hexdigest()) # 07105a4643a5c133207afd3ccd98badc</code></pre> <ul> <li>不管算法多么不同,摘要的功能始终不变</li> <li>对于相同的字符串使用同一个算法进行摘要,得到的值总是不变的</li> <li>使用不用算法对相同的字符串进行摘要,得到的值是不同的</li> <li>不管使用什么算法,使用hashlib的方式不变</li> <li><p>sha 算法 随着 算法复杂程度的增加 摘要的时间和空间成本都会增加</p></li> <li><p>用户登录</p></li> </ul> <pre><code>import hashlib usr = input("username: ") pwd = input("password: ") with open("userinfo") as f: for line in f: user, passwd, role = line.split("|") md5 = hashlib.md5() md5.update(bytes(pwd,encoding="utf-8")) md5_pwd = md5.hexdigest() if usr == user and md5_pwd == passwd: print("登录成功")</code></pre> <ul> <li>加盐</li> </ul> <pre><code>import hashlib md5 = hashlib.md5(bytes("salt", encoding="utf-8")) md5.update(b"min123") print(md5.hexdigest()) # f4ce519205cdd10528f9b0f0b54a8927</code></pre> <ul> <li>动态加盐</li> <li>用户名 密码</li> <li>使用用户名的一部分或者 直接使用整个用户名作为盐</li> </ul> <pre><code>import hashlib md5 = hashlib.md5(bytes("salt", encoding="utf-8")+b"min") md5.update(b"min123") print(md5.hexdigest()) # 6714cc6db8867ccbf8cb21f990e81937</code></pre> <ul> <li>对一个文件进行摘要算法,最后计算出这个文件的md5值</li> </ul> <pre><code>import hashlib md5 = hashlib.md5() md5.update(b"egg") md5.update(b"123") print(md5.hexdigest()) # 042c9076128b0658da027bf39d1dd4c3</code></pre> <ul> <li>不管算法多么不同,摘要的功能始终不变</li> <li>对于相同的字符串使用同一个算法进行摘要,得到的值总是不变的</li> <li>使用不用算法对相同的字符串进行摘要,得到的值是不同的</li> <li>不管使用什么算法,使用hashlib的方式不变</li> <li>sha 算法 随着 算法复杂程度的增加 摘要的时间和空间成本都会增加</li> <li>摘要算法</li> <li>密码的密文存储</li> <li>md5 加密认证 <ul> <li>正常的MD5算法</li> <li>加盐的</li> <li>动态加盐的</li> </ul></li> <li>文件的一致性验证,在文件的一致性校验中不能加盐 <ul> <li>在下载的时候 检查下载的文件和远程服务器上文件是否一致</li> <li>两台机器上的两个文件,检查这两个文件是否相等</li> </ul></li> </ul> <h2 id="configparse模块">9 configparse模块</h2> <ul> <li>该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键=值)。</li> </ul> <h3 id="创建文件">9.1 创建文件</h3> <ul> <li>来看一个好多软件的常见文档格式如下:</li> </ul> <pre><code>[DEFAULT] ServerAliveInterval = 45 Compression = yes CompressionLevel = 9 ForwardX11 = yes [bitbucket.org] User = hg [topsecret.server.com] Port = 50022 ForwardX11 = no</code></pre> <ul> <li>用python生成一个以上格式的文档</li> </ul> <pre><code>import configparser config = configparser.ConfigParser() config["DEFAULT"] = {'ServerAliveInterval': '45', 'Compression': 'yes', 'CompressionLevel': '9', 'ForwardX11':'yes' } config['bitbucket.org'] = {'User':'hg'} config['topsecret.server.com'] = {'Host Port':'50022','ForwardX11':'no'} with open('example.ini', 'w') as configfile: config.write(configfile)</code></pre> <h3 id="查找文件">9.2 查找文件</h3> <pre><code>import configparser config = configparser.ConfigParser() #---------------------------查找文件内容,基于字典的形式 print(config.sections()) # [] config.read('example.ini') print(config.sections()) # ['bitbucket.org', 'topsecret.server.com'] print('bytebong.com' in config) # False print('bitbucket.org' in config) # True print(config['bitbucket.org']["user"]) # hg print(config['DEFAULT']['Compression']) #yes print(config['topsecret.server.com']['ForwardX11']) #no print(config['bitbucket.org']) #<Section: bitbucket.org> for key in config['bitbucket.org']: # 注意,有default会默认default的键 print(key) print(config.options('bitbucket.org')) # 同for循环,找到'bitbucket.org'下所有键 print(config.items('bitbucket.org')) #找到'bitbucket.org'下所有键值对 print(config.get('bitbucket.org','compression')) # yes get方法Section下的key对应的value</code></pre> <h3 id="增删改操作">9.3 增删改操作</h3> <pre><code>import configparser config = configparser.ConfigParser() config.read('example.ini') config.add_section('yuan') config.remove_section('bitbucket.org') config.remove_option('topsecret.server.com',"forwardx11") config.set('topsecret.server.com','k1','11111') config.set('yuan','k2','22222') f = open('new2.ini', "w") config.write(f) f.close()</code></pre> <h2 id="logging模块">10 logging模块</h2> <pre><code>import logging logging.debug('debug message') # 排错信息 # 低级别 logging.info('info message') # 正常信息 logging.warning('warning message') # 警告信息 logging.error('error message') # 错误信息 logging.critical('critical message') # 严重错误信息 # 高级别</code></pre> <ul> <li>默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),默认的日志格式为日志级别:Logger名称:用户输出消息。</li> </ul> <h3 id="basicconfig">10.1 basicconfig</h3> <ul> <li>灵活配置日志级别,日志格式,输出位置:</li> </ul> <pre><code>import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename='/tmp/test.log', filemode='w') logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message')</code></pre> <ul> <li>basicconfig 简单 能做的事情相对少 <ul> <li>中文的乱码问题 解决不了</li> <li>不能同时往文件和屏幕上输出</li> </ul></li> </ul> <pre><code>import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename='test.log', filemode='w') try: int(input("num >>> ")) except ValueError: logging.error('error message> 输入的值不是一个数字')</code></pre> <ul> <li>配置参数:</li> </ul> <pre><code>logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有: filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。 filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。 format:指定handler使用的日志显示格式。 datefmt:指定日期时间格式。 level:设置rootlogger(后边会讲解具体概念)的日志级别 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。 format参数中可能用到的格式化串: %(name)s Logger的名字 %(levelno)s 数字形式的日志级别 %(levelname)s 文本形式的日志级别 %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有 %(filename)s 调用日志输出函数的模块的文件名 %(module)s 调用日志输出函数的模块名 %(funcName)s 调用日志输出函数的函数名 %(lineno)d 调用日志输出函数的语句所在的代码行 %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示 %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数 %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 %(thread)d 线程ID。可能没有 %(threadName)s 线程名。可能没有 %(process)d 进程ID。可能没有 %(message)s用户输出的消息</code></pre> <h3 id="logger对象配置">10.2 logger对象配置</h3> <pre><code>import logging logger = logging.getLogger() # 创建一个handler,用于写入日志文件 fh = logging.FileHandler('test.log',encoding='utf-8') # 再创建一个handler,用于输出到控制台 ch = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setLevel(logging.DEBUG) fh.setFormatter(formatter) ch.setFormatter(formatter) logger.addHandler(fh) #logger对象可以添加多个fh和ch对象 logger.addHandler(ch) logger.debug('logger debug message') logger.info('logger info message') logger.warning('logger warning message') logger.error('logger error message') logger.critical('logger critical message')</code></pre> <pre><code>import logging logger = logging.getLogger() fh = logging.FileHandler("log.log", encoding="utf-8") sh = logging.StreamHandler() # 创建一个屏幕控制对象 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') formatter2 = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - [line:%(lineno)d]- %(message)s') # 文件操作符 和 格式关联 fh.setFormatter(formatter) sh.setFormatter(formatter2) # logger 对象 和 文件操作符 关联 logger.addHandler(fh) logger.addHandler(sh) logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message')</code></pre> <ul> <li>logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。另外,可以通过:logger.setLevel(logging.Debug)设置级别,当然,也可以通过</li> <li>fh.setLevel(logging.Debug)单对文件流设置某个级别。</li> <li>程序的充分解耦</li> <li><p>让程序变的高可定制化</p></li> <li><p><strong>转自</strong> :http://www.cnblogs.com/Eva-J/articles/7228075.html</p></li> </ul> </div> <p>转载于:https://www.cnblogs.com/xiaoqshuo/p/9717242.html</p> </div> </div> </div> </div> </div> <!--PC和WAP自适应版--> <div id="SOHUCS" sid="1279830492102803456"></div> <script type="text/javascript" src="/views/front/js/chanyan.js"></script> <!-- 文章页-底部 动态广告位 --> <div class="youdao-fixed-ad" id="detail_ad_bottom"></div> </div> <div class="col-md-3"> <div class="row" id="ad"> <!-- 文章页-右侧1 动态广告位 --> <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_1"> </div> </div> <!-- 文章页-右侧2 动态广告位 --> <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_2"></div> </div> <!-- 文章页-右侧3 动态广告位 --> <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_3"></div> </div> </div> </div> </div> </div> </div> <div class="container"> <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(Python - - 模块 - - 常用模块)</h4> <div id="paradigm-article-related"> <div class="recommend-post mb30"> <ul class="widget-links"> <li><a href="/article/1903224733122490368.htm" title="Jira获取story信息更新子任务状态脚本技术实现" target="_blank">Jira获取story信息更新子任务状态脚本技术实现</a> <span class="text-muted">吾爱乐享</span> <a class="tag" taget="_blank" href="/search/w/1.htm">w</a><a class="tag" taget="_blank" href="/search/w/1.htm">w</a><a class="tag" taget="_blank" href="/search/w/1.htm">w</a><a class="tag" taget="_blank" href="/search/w/1.htm">w</a><a class="tag" taget="_blank" href="/search/./1.htm">.</a><a class="tag" taget="_blank" href="/search/f/1.htm">f</a><a class="tag" taget="_blank" href="/search/e/1.htm">e</a><a class="tag" taget="_blank" href="/search/n/1.htm">n</a> <div>title:Jira获取story信息更新子任务状态脚本技术实现tags:-Jiracategories:-Jira一、项目背景在Jira项目管理系统中,当story主任务处于特定状态(如“READYFORPM”或“已关闭”)时,需要对其所有子任务的状态进行更新。为了实现这一自动化操作,编写了一个Python脚本,以提高工作效率和准确性。二、技术选型编程语言:Python,因其简洁易读的语法和丰富</div> </li> <li><a href="/article/1903224480918990848.htm" title="元数据驱动的设想" target="_blank">元数据驱动的设想</a> <span class="text-muted">吾爱乐享</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>title:元数据驱动的设想tags:pythoncategories:python文章目录1.背景针对相似结构的表单,为了提高ui自动化编写效率,减少以减少重复工作,设想是否可以设计一个针对neoUI2.0通过元数据驱动的方式适应不同业务对象的测试框架2.设计元数据模型-字段名-字段类型-是否必填-是否只读-默认值-业务逻辑(可选,后期扩展)3.构建自动化测试框架利用现有的RF框架已实现的功能,</div> </li> <li><a href="/article/1903224353433120768.htm" title="在Robot Framework中Run Keyword If的用法" target="_blank">在Robot Framework中Run Keyword If的用法</a> <span class="text-muted">吾爱乐享</span> <a class="tag" taget="_blank" href="/search/Robot/1.htm">Robot</a><a class="tag" taget="_blank" href="/search/Framework/1.htm">Framework</a><a class="tag" taget="_blank" href="/search/Robot/1.htm">Robot</a><a class="tag" taget="_blank" href="/search/Framework/1.htm">Framework</a> <div>基本用法使用ELSE使用ELSEIF使用内置变量使用Python表达式本文永久更新地址:在RobotFramework中,RunKeywordIf是一个条件执行的关键字,它允许根据某个条件来决定是否执行某个关键字。下面是RunKeywordIf的基本用法:RunKeywordIfconditionkeyword...ELSEkeyword这里的condition是一个表达式,如果该表达式为真(即条</div> </li> <li><a href="/article/1903218047435468800.htm" title="使用 Resilience4j 实现重试" target="_blank">使用 Resilience4j 实现重试</a> <span class="text-muted">树懒_Zz</span> <a class="tag" taget="_blank" href="/search/Spring/1.htm">Spring</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/cloud/1.htm">cloud</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a> <div>在本文中,我们将首先简要介绍Resilience4j,然后深入研究其重试模块。我们将了解何时以及如何使用它,以及它提供哪些功能.什么是Resilience4j?应用程序通过网络通信时,许多事情都可能出错。由于连接中断、网络故障、上游服务不可用等原因,操作可能会超时或失败。应用程序可能会相互过载、无响应,甚至崩溃。Resilience4j是一个Java库,可帮助我们构建具有弹性和容错能力的应用程序。</div> </li> <li><a href="/article/1903216406665687040.htm" title="MyBatis-plus 2.x -> 3.x 版本升级笔记" target="_blank">MyBatis-plus 2.x -> 3.x 版本升级笔记</a> <span class="text-muted">三只松鼠@</span> <a class="tag" taget="_blank" href="/search/%E5%B7%A5%E4%BD%9C%E6%97%A5%E5%B8%B8/1.htm">工作日常</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a> <div>参考链接:https://github.com/baomidou/mybatis-plus/issues/32621.官方更新日志升级JDK8+优化性能Wrapper支持lambda语法模块化MP合理的分配各个包结构移除com.baomidou.mybatisplus.extension.injector.methods.additional包下的过时类fix:初始化TableInfo中遇到多个字</div> </li> <li><a href="/article/1903210353773309952.htm" title="人工智能革命:技术演进图谱与人类文明重构路径" target="_blank">人工智能革命:技术演进图谱与人类文明重构路径</a> <span class="text-muted">A达峰绮</span> <a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E9%87%8D%E6%9E%84/1.htm">重构</a><a class="tag" taget="_blank" href="/search/%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB/1.htm">经验分享</a><a class="tag" taget="_blank" href="/search/%E5%9B%BE%E5%BD%A2%E7%BB%98%E5%88%B6/1.htm">图形绘制</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86/1.htm">数据处理</a><a class="tag" taget="_blank" href="/search/AI/1.htm">AI</a> <div>当GPT-4在2023年3月通过注册会计师考试时,其财务分析模块展现的推理能力已超越85%的人类考生。这个标志性事件背后,折射出人工智能正在突破认知型工作的最后防线。我们正在见证的,不仅是技术迭代,更是人类文明范式的根本性转变。一、算力奇点降临:AI基础设施的指数级进化量子计算与神经形态芯片的融合正在重塑算力边界。IBM最新数据显示,其量子体积(QuantumVolume)从2020年的64跃升至</div> </li> <li><a href="/article/1903208842167119872.htm" title="Python实战:开发经典猜拳游戏(石头剪刀布)" target="_blank">Python实战:开发经典猜拳游戏(石头剪刀布)</a> <span class="text-muted">藍海琴泉</span> <a class="tag" taget="_blank" href="/search/%E6%B8%B8%E6%88%8F/1.htm">游戏</a> <div>目录引言:为什么选择猜拳游戏作为入门项目?第一部分:基础知识点与代码实现1.游戏逻辑与流程2.代码分步实现2.1导入必要模块2.2定义游戏规则函数2.3生成计算机选择2.4判断胜负逻辑2.5主循环与交互3.代码运行效果示例第二部分:功能扩展与优化1.添加计分系统2.支持多轮游戏与退出选择3.增加图形化界面(可选)第三部分:进一步学习方向1.深化游戏功能2.学习相关知识3.书籍与资源推荐适合人群:编</div> </li> <li><a href="/article/1903208712714121216.htm" title="Python函数完全解读:从零基础到高阶实战" target="_blank">Python函数完全解读:从零基础到高阶实战</a> <span class="text-muted">藍海琴泉</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>目标读者:编程新手|转行者|需系统掌握函数用法的开发者目录一、函数是什么?为什么需要函数?二、函数基础语法详解1.定义与调用2.返回值:函数的输出结果3.参数传递机制4.案例:计算BMI指数三、变量作用域:理解局部与全局1.局部变量2.全局变量四、函数进阶:lambda与高阶函数1.lambda匿名函数2.高阶函数五、函数高级特性1.装饰器:增强函数功能2.递归函数六、实战案例:文件处理工具一、函</div> </li> <li><a href="/article/1903205689669513216.htm" title="本地部署deepseek-r1:14b 批量调用 Python调用本地deepseek-r1:14b实现对本地数据库的AI管理" target="_blank">本地部署deepseek-r1:14b 批量调用 Python调用本地deepseek-r1:14b实现对本地数据库的AI管理</a> <span class="text-muted">朴拙Python交易猿</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>这篇文章主要为大家详细介绍了Python如何基于DeepSeek模型,调用本地deepseek-r1:14b实现对本地数据库的AI管理场景描述基于DeepSeek模型,实现对本地数据库的AI管理。实现思路1、本地python+flask搭建个WEB,配置数据源。2、通过DeepSeek模型根据用户输入的文字需求,自动生成SQL语句。3、通过SQL执行按钮,实现对数据库的增删改查。模型服务方法1启动</div> </li> <li><a href="/article/1903202023780708352.htm" title="Matplotlib 柱形图" target="_blank">Matplotlib 柱形图</a> <span class="text-muted">lly202406</span> <a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>Matplotlib柱形图引言在数据可视化领域,柱形图是一种非常常见且强大的图表类型。它能够帮助我们直观地比较不同类别或组之间的数据大小。Matplotlib,作为Python中最受欢迎的数据可视化库之一,提供了丰富的绘图功能,其中包括创建柱形图。本文将详细介绍Matplotlib中的柱形图,包括其基本用法、高级特性以及如何进行优化。基本用法安装Matplotlib在开始使用Matplotlib之</div> </li> <li><a href="/article/1903199881921622016.htm" title="Matplotlib如何创建交互式图表?" target="_blank">Matplotlib如何创建交互式图表?</a> <span class="text-muted">EdgarBertram</span> <a class="tag" taget="_blank" href="/search/matplotlib/1.htm">matplotlib</a> <div>Matplotlib是一个强大的Python绘图库,它可以用于生成高质量的静态图像。然而,Matplotlib同样支持创建交互式图表,这对于数据分析和可视化非常有用。交互式图表允许用户通过交互方式探索数据,例如缩放、平移或者查询数据点。下面我们将详细介绍如何使用Matplotlib创建交互式图表。一、安装与配置首先,确保你已经安装了Matplotlib库。你可以使用pip来安装:bash复制代码p</div> </li> <li><a href="/article/1903196729847640064.htm" title="如何用PHP开发一个api数据接口" target="_blank">如何用PHP开发一个api数据接口</a> <span class="text-muted">幽蓝计划</span> <a class="tag" taget="_blank" href="/search/php/1.htm">php</a> <div>对于一个iOS开发者来说,我一直觉得会写接口是一件很酷的事情,因为它可以实时修改前台数据,而不像App一样需要更新版本和接受审核。更重要的是,它意味着你的技术完成了一个闭环,可以独自完成一整个项目的开发。PHP是我接触的第一个脚本语言,使用之后更是感觉PHP功能强大,开发过程非常友好方便,虽然之后也学习过Python、JavaScript等语言,但现在还是习惯使用PHP,下面就来介绍一下如何用PH</div> </li> <li><a href="/article/1903187019757056000.htm" title="对MCP工作流的一些个人认知" target="_blank">对MCP工作流的一些个人认知</a> <span class="text-muted">持续学习的老赵</span> <a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a> <div>最近在学习MCP系统,虽尚未深入掌握,但已对其工作原理有了初步认识,在此分享下学习收获。MCP是一套能实现客户端、多种服务与大模型协同工作的系统,能处理任务请求并及时反馈。其工作流程如下:一、获取并更新服务使用方法(一)收集整理使用方法MCP正常运行依赖于对各类服务使用方法的了解,这要靠已在系统注册且可识别的功能模块。一旦有新模块注册或旧模块更新,系统会自动检测并获取其使用方法信息。MCP订阅服务</div> </li> <li><a href="/article/1903186137053196288.htm" title="【入门初级篇】报表基础操作与功能介绍" target="_blank">【入门初级篇】报表基础操作与功能介绍</a> <span class="text-muted">#六脉神剑</span> <a class="tag" taget="_blank" href="/search/%E4%BD%8E%E4%BB%A3%E7%A0%81/1.htm">低代码</a><a class="tag" taget="_blank" href="/search/myBuilder/1.htm">myBuilder</a><a class="tag" taget="_blank" href="/search/%E4%BA%A7%E5%93%81%E8%BF%90%E8%90%A5/1.htm">产品运营</a> <div>【入门初级篇】报表的基本操作与功能介绍视频要点(1)报表组件的创建(2)指标组件的使用:一级、二级指标操作演示(3)表格属性设置介绍(4)图表属性设置介绍(5)报表预览:绑定静态数据(6)介绍myBuilder内部模块:用报表低代码开发的示例介绍点击访问myBuilder产品运营平台CSDN站内资源下载myBuilder交流请加微信:MyBuilder88</div> </li> <li><a href="/article/1903179194553135104.htm" title="SOFAStack-00-sofa 技术栈概览" target="_blank">SOFAStack-00-sofa 技术栈概览</a> <span class="text-muted">老马啸西风</span> <a class="tag" taget="_blank" href="/search/sofa/1.htm">sofa</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a><a class="tag" taget="_blank" href="/search/%E7%9B%91%E6%8E%A7/1.htm">监控</a><a class="tag" taget="_blank" href="/search/%E9%98%BF%E9%87%8C%E4%BA%91/1.htm">阿里云</a><a class="tag" taget="_blank" href="/search/%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84/1.htm">系统架构</a> <div>SOFAStack前言大家好,我是老马。sofastack其实出来很久了,第一次应该是在2022年左右开始关注,但是一直没有深入研究。最近想学习一下SOFA对于生态的设计和思考。核心项目⚙️SOFABootGitHub:sofastack/sofa-boot|★3.8k功能:企业级SpringBoot增强框架,支持模块化开发、类隔离、日志隔离,提供健康检查、异步初始化等特性。SOFARPCGitH</div> </li> <li><a href="/article/1903178436948586496.htm" title="使用E2B数据分析沙盒进行文件分析" target="_blank">使用E2B数据分析沙盒进行文件分析</a> <span class="text-muted">qahaj</span> <a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/1.htm">数据挖掘</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>使用E2B数据分析沙盒进行文件分析在现代数据分析中,运行环境的安全性与灵活性是确保数据处理高效可靠的关键因素。E2B提供了一个数据分析沙盒,能够在隔离的环境中安全地执行代码,非常适合构建诸如代码解释器或类似于ChatGPT的高级数据分析工具。在这篇文章中,我将演示如何使用E2B的数据分析沙盒来对上传的文件进行分析,为您提供一个强大的Python代码示例。核心原理解析E2B的数据分析沙盒为开发者提供</div> </li> <li><a href="/article/1903171250159677440.htm" title="Python笔记——DeprecationWarning" target="_blank">Python笔记——DeprecationWarning</a> <span class="text-muted">小橘猫cate</span> <a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>定义如下阶跃函数时出现警告,defstep_function(x):returnnp.array(x>0,dtype=np.int)DeprecationWarning:`np.int`isadeprecatedaliasforthebuiltin`int`.Tosilencethiswarning,use`int`byitself.Doingthiswillnotmodifyanybehavio</div> </li> <li><a href="/article/1903170368412119040.htm" title="使用 ArcGIS 和 Python 进行地理信息系统(GIS)分析" target="_blank">使用 ArcGIS 和 Python 进行地理信息系统(GIS)分析</a> <span class="text-muted">scaFHIO</span> <a class="tag" taget="_blank" href="/search/arcgis/1.htm">arcgis</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>在本篇文章中,我们将探讨如何利用ArcGIS和Python进行地理信息系统(GIS)分析。ArcGIS是由Esri开发和维护的一系列GIS软件,包括客户端、服务器和在线解决方案。本文主要聚焦于如何使用Python和arcgis库来实现GIS功能。技术背景介绍ArcGIS提供了功能强大的工具来进行矢量和栅格分析、地理编码、地图制作以及路线和路径规划。通过arcgisPython库,我们可以访问Esr</div> </li> <li><a href="/article/1903166194966392832.htm" title="DeprecationWarning: 无效的转义序列‘\/‘解决方案" target="_blank">DeprecationWarning: 无效的转义序列‘\/‘解决方案</a> <span class="text-muted">数据科学智慧</span> <a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a><a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a> <div>DeprecationWarning:无效的转义序列’/'解决方案在Python编程中,您可能会遇到"DeprecationWarning:无效的转义序列’/'"的警告消息。这个警告通常在您尝试使用无效的转义序列时出现,例如在正则表达式或字符串中。本文将为您提供解决方案,以解决这个问题。首先,让我们了解一下转义序列的概念。在Python中,某些字符前面带有反斜杠(\),以表示特殊含义,例如换行符(</div> </li> <li><a href="/article/1903158369250766848.htm" title="Linux驱动开发实战之SRIO驱动(二)基于Tsi721驱动" target="_blank">Linux驱动开发实战之SRIO驱动(二)基于Tsi721驱动</a> <span class="text-muted">niuTaylor</span> <a class="tag" taget="_blank" href="/search/SRIO%E9%A9%B1%E5%8A%A8%E5%AE%9E%E6%88%98/1.htm">SRIO驱动实战</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91/1.htm">驱动开发</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/SRIO/1.htm">SRIO</a> <div>常用驱动介绍在RapidIO系统中,TSI721是一款常用的RapidIO交换芯片,其驱动程序和相关模块负责管理和优化数据传输,包括DMA(直接内存访问)操作。以下是您提到的各个模块的作用概述:rapidio.ko:这是RapidIO核心模块,为RapidIO子系统提供基础支持。它负责管理RapidIO设备、维护RapidIO网络拓扑结构,以及处理RapidIO协议的底层细节。rio_cm.ko:</div> </li> <li><a href="/article/1903149042179829760.htm" title="python做飞机大战让敌机打子弹_python(pygame)滑稽大战(类似飞机大战) 教程" target="_blank">python做飞机大战让敌机打子弹_python(pygame)滑稽大战(类似飞机大战) 教程</a> <span class="text-muted">青云若水</span> <div>初始准备工作本项目使用的python3版本(如果你用python2,我不知会怎么样)Ide推荐大家选择pycharm(不同ide应该没影响)需要安装第三方库pygame,pygame安装方法(windows电脑,mac系统本人实测与pygame不兼容,强行运行本项目卡成ppt)电脑打开cmd命令窗口,输入pip3installpygame补充说明:由于众所周知的原因,安装过程中下载可能十分缓慢,甚</div> </li> <li><a href="/article/1903148033500049408.htm" title="利用Python和深度学习方法实现手写数字识别的高精度解决方案——从数据预处理到模型优化的全流程解析" target="_blank">利用Python和深度学习方法实现手写数字识别的高精度解决方案——从数据预处理到模型优化的全流程解析</a> <span class="text-muted">快撑死的鱼</span> <a class="tag" taget="_blank" href="/search/Python%E7%AE%97%E6%B3%95%E7%B2%BE%E8%A7%A3/1.htm">Python算法精解</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/1.htm">深度学习</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>利用Python和深度学习方法实现手写数字识别的高精度解决方案——从数据预处理到模型优化的全流程解析在人工智能的众多应用领域中,手写数字识别是一项经典且具有重要实际应用价值的任务。随着深度学习技术的飞速发展,通过构建和训练神经网络模型,手写数字识别的精度已经可以达到99%以上。本文将以Python为主要编程语言,结合深度学习的核心技术,详细解析手写数字识别的实现过程,并探讨如何进一步优化模型以提高</div> </li> <li><a href="/article/1903148032019460096.htm" title="python之连连看游戏" target="_blank">python之连连看游戏</a> <span class="text-muted">CrMylive.</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E6%B8%B8%E6%88%8F/1.htm">游戏</a><a class="tag" taget="_blank" href="/search/pygame/1.htm">pygame</a> <div>实现一个简单的连连看游戏需要用到pygame库和一些基本的数据结构和算法。导入pygame库在程序开始之前,首先需要导入pygame库。在Python中,可以使用以下代码导入pygame库:importpygame初始化Pygame在导入pygame库之后,需要使用以下代码初始化pygame:pygame.init()设置游戏窗口设置游戏窗口的大小、标题等属性。可以使用以下代码设置游戏窗口大小为6</div> </li> <li><a href="/article/1903144120109559808.htm" title="Python, Java, C ++开发全球热能动态监测APP" target="_blank">Python, Java, C ++开发全球热能动态监测APP</a> <span class="text-muted">Geeker-2025</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/c%2B%2B/1.htm">c++</a> <div>开发一个“全球热能动态监测APP”是一个非常有意义的想法,尤其是在能源管理和环境保护领域。以下是开发该APP的详细思路和技术实现方案,分别针对Python、Java和C++。---###**功能需求分析**1.**全球热能数据展示**:-各国或地区的热能生产、消费和进出口数据。-实时监测热能动态(如发电厂的热能输出、温度变化等)。2.**地图可视化**:-在地图上标注热能发电厂的位置。-使用颜色或</div> </li> <li><a href="/article/1903140843557023744.htm" title="css预编译" target="_blank">css预编译</a> <span class="text-muted">风不在乎</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/css/1.htm">css</a><a class="tag" taget="_blank" href="/search/css/1.htm">css</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/scss/1.htm">scss</a><a class="tag" taget="_blank" href="/search/less/1.htm">less</a><a class="tag" taget="_blank" href="/search/stylus/1.htm">stylus</a> <div>前言定义我们使用css来编写样式,但是随着样式效果的多样化以及复杂化,css变量常量的缺失、语法的呆板等一成不变的写法就会十分臃肿难以维护。所以基于css扩展了一套属于自己的语法,通过专门的编程语言,扩展css的编程能力,在编译成css。常见的库有less、scss/sass、stylus等。特点完美兼容css代码,结构清晰便于扩展支持css定义变量常量、代码嵌套提供函数,支持循环语句支持模块化,</div> </li> <li><a href="/article/1903138070908170240.htm" title="asp.net mvc mysql 开源项目_【开源项目SugarSite】ASP.NET MVC+ Layui+ SqlSugar+RestSharp项目讲解..." target="_blank">asp.net mvc mysql 开源项目_【开源项目SugarSite】ASP.NET MVC+ Layui+ SqlSugar+RestSharp项目讲解...</a> <span class="text-muted">weixin_39805732</span> <a class="tag" taget="_blank" href="/search/asp.net/1.htm">asp.net</a><a class="tag" taget="_blank" href="/search/mvc/1.htm">mvc</a><a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE/1.htm">开源项目</a> <div>SugarSite一个前端支持移动端的企业网站,目前只支持了简单功能,后续还会加上论坛等。源码GIT地址:技术介绍Layui个人而言不喜欢引用一堆东西,越简洁越好,layui正好能够满足我的这种需求,它是一款轻量级UI,JS部分都是采用模块化设计(AMD),对移动端支持比较不错。唯一不足是目前支持的组件有些少,需要有一定前端扩展能力的人才可以顺心使用。用法:例如我想用form.js和uploda.</div> </li> <li><a href="/article/1903137944076611584.htm" title="动物识别系统代码python_动物识别系统__代码" target="_blank">动物识别系统代码python_动物识别系统__代码</a> <span class="text-muted">weixin_39812065</span> <a class="tag" taget="_blank" href="/search/%E5%8A%A8%E7%89%A9%E8%AF%86%E5%88%AB%E7%B3%BB%E7%BB%9F%E4%BB%A3%E7%A0%81python/1.htm">动物识别系统代码python</a> <div>1动物识别专家系统动物识别专家系统是流行的专家系统实验模型,它用产生式规则来表示知识,共15条规则、可以识别七种动物,这些规则既少又简单,可以改造他们,也可以加进新的规则,还可以用来识别其他东西的新规则来取代这些规则。动物识别15条规则的中文表示是:规则1:如果:动物有毛发则:该动物是哺乳动物规则2:如果:动物有奶则:该单位是哺乳动物规则3:如果:该动物有羽毛则:该动物是鸟规则4:如果:动物会飞,</div> </li> <li><a href="/article/1903137944517013504.htm" title="动物识别系统代码python_动物识别系统代码" target="_blank">动物识别系统代码python_动物识别系统代码</a> <span class="text-muted">weixin_39862794</span> <a class="tag" taget="_blank" href="/search/%E5%8A%A8%E7%89%A9%E8%AF%86%E5%88%AB%E7%B3%BB%E7%BB%9F%E4%BB%A3%E7%A0%81python/1.htm">动物识别系统代码python</a> <div>简易动物识别专家系统源代码(调试无错!)#includevoidbirds(){inta;printf("**************************************\n");printf("1.长腿,长脖子,黑色,不会飞。\n");printf("2.不会飞,会游泳,黑色.\n");printf("3.善飞\n");printf("4.无上述特征\n");printf("****</div> </li> <li><a href="/article/1903134159765827584.htm" title="Python深浅拷贝" target="_blank">Python深浅拷贝</a> <span class="text-muted">Karl_zhujt</span> <a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>文章目录1概述2数据类型2.1可变类型2.2不可变类型3深浅拷贝3.1浅拷贝3.2深拷贝4深浅拷贝对数据类型的影响4.1对于不可变类型的影响4.2对于可变类型的影响4.3总结5实现机制5.1copy5.2id6示例6.1普通赋值6.2浅拷贝可变类型6.3浅拷贝不可变类型6.4深拷贝可变类型6.5深拷贝不可变类型7注意事项1概述在Python中,可变类型和不可变类型的拷贝行为有所不同。理解它们的区别</div> </li> <li><a href="/article/1903131115309297664.htm" title="基于 EMA12 指标结合 iTick 外汇报价 API 、股票报价API、指数报价API的量化策略编写与回测" target="_blank">基于 EMA12 指标结合 iTick 外汇报价 API 、股票报价API、指数报价API的量化策略编写与回测</a> <span class="text-muted"></span> <div>iTick提供了强大的外汇报价API、股票报价API和指数报价API服务,为量化策略的开发提供了丰富的数据支持。本文将详细介绍如何使用Python结合EMA12指标和iTick的报价API来构建一个简单的量化交易策略,并对该策略进行回测。1.引言在量化交易领域,技术指标是构建交易策略的重要基础。iTick提供了强大的外汇报价API、股票报价API和指数报价API服务,为量化策略的开发提供了丰富的数</div> </li> <li><a href="/article/85.htm" title="ztree异步加载" target="_blank">ztree异步加载</a> <span class="text-muted">3213213333332132</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/Ajax/1.htm">Ajax</a><a class="tag" taget="_blank" href="/search/json/1.htm">json</a><a class="tag" taget="_blank" href="/search/Web/1.htm">Web</a><a class="tag" taget="_blank" href="/search/ztree/1.htm">ztree</a> <div>相信新手用ztree的时候,对异步加载会有些困惑,我开始的时候也是看了API花了些时间才搞定了异步加载,在这里分享给大家。 我后台代码生成的是json格式的数据,数据大家按各自的需求生成,这里只给出前端的代码。 设置setting,这里只关注async属性的配置 var setting = { //异步加载配置 </div> </li> <li><a href="/article/212.htm" title="thirft rpc 具体调用流程" target="_blank">thirft rpc 具体调用流程</a> <span class="text-muted">BlueSkator</span> <a class="tag" taget="_blank" href="/search/%E4%B8%AD%E9%97%B4%E4%BB%B6/1.htm">中间件</a><a class="tag" taget="_blank" href="/search/rpc/1.htm">rpc</a><a class="tag" taget="_blank" href="/search/thrift/1.htm">thrift</a> <div>Thrift调用过程中,Thrift客户端和服务器之间主要用到传输层类、协议层类和处理类三个主要的核心类,这三个类的相互协作共同完成rpc的整个调用过程。在调用过程中将按照以下顺序进行协同工作:         (1)     将客户端程序调用的函数名和参数传递给协议层(TProtocol),协议</div> </li> <li><a href="/article/339.htm" title="异或运算推导, 交换数据" target="_blank">异或运算推导, 交换数据</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a><a class="tag" taget="_blank" href="/search/%E5%BC%82%E6%88%96/1.htm">异或</a><a class="tag" taget="_blank" href="/search/%5E/1.htm">^</a> <div>/* * 5 0101 * 9 1010 * * 5 ^ 5 * 0101 * 0101 * ----- * 0000 * 得出第一个规律: 相同的数进行异或, 结果是0 * * 9 ^ 5 ^ 6 * 1010 * 0101 * ---- * 1111 * * 1111 * 0110 * ---- * 1001 </div> </li> <li><a href="/article/466.htm" title="事件源对象" target="_blank">事件源对象</a> <span class="text-muted">周华华</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a> <div><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml&q</div> </li> <li><a href="/article/593.htm" title="MySql配置及相关命令" target="_blank">MySql配置及相关命令</a> <span class="text-muted">g21121</span> <a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a> <div>        MySQL安装完毕后我们需要对它进行一些设置及性能优化,主要包括字符集设置,启动设置,连接优化,表优化,分区优化等等。           一 修改MySQL密码及用户      </div> </li> <li><a href="/article/720.htm" title="[简单]poi删除excel 2007超链接" target="_blank">[简单]poi删除excel 2007超链接</a> <span class="text-muted">53873039oycg</span> <a class="tag" taget="_blank" href="/search/Excel/1.htm">Excel</a> <div>      采用解析sheet.xml方式删除超链接,缺点是要打开文件2次,代码如下:      public void removeExcel2007AllHyperLink(String filePath) throws Exception { OPCPackage ocPkg = OPCPac</div> </li> <li><a href="/article/847.htm" title="Struts2添加 open flash chart" target="_blank">Struts2添加 open flash chart</a> <span class="text-muted">云端月影</span> <div>准备以下开源项目: 1. Struts 2.1.6 2. Open Flash Chart 2 Version 2 Lug Wyrm Charmer (28th, July 2009) 3. jofc2,这东西不知道是没做好还是什么意思,好像和ofc2不怎么匹配,最好下源码,有什么问题直接改。 4. log4j 用eclipse新建动态网站,取名OFC2Demo,将Struts2 l</div> </li> <li><a href="/article/974.htm" title="spring包详解" target="_blank">spring包详解</a> <span class="text-muted">aijuans</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a> <div> 下载的spring包中文件及各种包众多,在项目中往往只有部分是我们必须的,如果不清楚什么时候需要什么包的话,看看下面就知道了。 aspectj目录下是在Spring框架下使用aspectj的源代码和测试程序文件。Aspectj是java最早的提供AOP的应用框架。 dist 目录下是Spring 的发布包,关于发布包下面会详细进行说明。 docs&nb</div> </li> <li><a href="/article/1101.htm" title="网站推广之seo概念" target="_blank">网站推广之seo概念</a> <span class="text-muted">antonyup_2006</span> <a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/Web/1.htm">Web</a><a class="tag" taget="_blank" href="/search/%E5%BA%94%E7%94%A8%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">应用服务器</a><a class="tag" taget="_blank" href="/search/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E/1.htm">搜索引擎</a><a class="tag" taget="_blank" href="/search/Google/1.htm">Google</a> <div>   持续开发一年多的b2c网站终于在08年10月23日上线了。作为开发人员的我在修改bug的同时,准备了解下网站的推广分析策略。     所谓网站推广,目的在于让尽可能多的潜在用户了解并访问网站,通过网站获得有关产品和服务等信息,为最终形成购买决策提供支持。     网站推广策略有很多,seo,email,adv</div> </li> <li><a href="/article/1228.htm" title="单例模式,sql注入,序列" target="_blank">单例模式,sql注入,序列</a> <span class="text-muted">百合不是茶</span> <a class="tag" taget="_blank" href="/search/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/1.htm">单例模式</a><a class="tag" taget="_blank" href="/search/%E5%BA%8F%E5%88%97/1.htm">序列</a><a class="tag" taget="_blank" href="/search/sql%E6%B3%A8%E5%85%A5/1.htm">sql注入</a><a class="tag" taget="_blank" href="/search/%E9%A2%84%E7%BC%96%E8%AF%91/1.htm">预编译</a> <div>  序列在前面写过有关的博客,也有过总结,但是今天在做一个JDBC操作数据库的相关内容时 需要使用序列创建一个自增长的字段  居然不会了,所以将序列写在本篇的前面    1,序列是一个保存数据连续的增长的一种方式; 序列的创建; CREATE SEQUENCE seq_pro 2 INCREMENT BY 1 -- 每次加几个 3 </div> </li> <li><a href="/article/1355.htm" title="Mockito单元测试实例" target="_blank">Mockito单元测试实例</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95/1.htm">单元测试</a><a class="tag" taget="_blank" href="/search/mockito/1.htm">mockito</a> <div>Mockito单元测试实例: public class SettingServiceTest { private List<PersonDTO> personList = new ArrayList<PersonDTO>(); @InjectMocks private SettingPojoService settin</div> </li> <li><a href="/article/1482.htm" title="精通Oracle10编程SQL(9)使用游标" target="_blank">精通Oracle10编程SQL(9)使用游标</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/plsql/1.htm">plsql</a> <div>/* *使用游标 */ --显示游标 --在显式游标中使用FETCH...INTO语句 DECLARE CURSOR emp_cursor is select ename,sal from emp where deptno=1; v_ename emp.ename%TYPE; v_sal emp.sal%TYPE; begin ope</div> </li> <li><a href="/article/1609.htm" title="【Java语言】动态代理" target="_blank">【Java语言】动态代理</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/java%E8%AF%AD%E8%A8%80/1.htm">java语言</a> <div>  JDK接口动态代理 JDK自带的动态代理通过动态的根据接口生成字节码(实现接口的一个具体类)的方式,为接口的实现类提供代理。被代理的对象和代理对象通过InvocationHandler建立关联   package com.tom; import com.tom.model.User; import com.tom.service.IUserService; </div> </li> <li><a href="/article/1736.htm" title="Java通信之URL通信基础" target="_blank">Java通信之URL通信基础</a> <span class="text-muted">白糖_</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/jdk/1.htm">jdk</a><a class="tag" taget="_blank" href="/search/webservice/1.htm">webservice</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE/1.htm">网络协议</a><a class="tag" taget="_blank" href="/search/ITeye/1.htm">ITeye</a> <div>java对网络通信以及提供了比较全面的jdk支持,java.net包能让程序员直接在程序中实现网络通信。 在技术日新月异的现在,我们能通过很多方式实现数据通信,比如webservice、url通信、socket通信等等,今天简单介绍下URL通信。 学习准备:建议首先学习java的IO基础知识   URL是统一资源定位器的简写,URL可以访问Internet和www,可以通过url</div> </li> <li><a href="/article/1863.htm" title="博弈Java讲义 - Java线程同步 (1)" target="_blank">博弈Java讲义 - Java线程同步 (1)</a> <span class="text-muted">boyitech</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%A4%9A%E7%BA%BF%E7%A8%8B/1.htm">多线程</a><a class="tag" taget="_blank" href="/search/%E5%90%8C%E6%AD%A5/1.htm">同步</a><a class="tag" taget="_blank" href="/search/%E9%94%81/1.htm">锁</a> <div>  在并发编程中经常会碰到多个执行线程共享资源的问题。例如多个线程同时读写文件,共用数据库连接,全局的计数器等。如果不处理好多线程之间的同步问题很容易引起状态不一致或者其他的错误。    同步不仅可以阻止一个线程看到对象处于不一致的状态,它还可以保证进入同步方法或者块的每个线程,都看到由同一锁保护的之前所有的修改结果。处理同步的关键就是要正确的识别临界条件(cri</div> </li> <li><a href="/article/1990.htm" title="java-给定字符串,删除开始和结尾处的空格,并将中间的多个连续的空格合并成一个。" target="_blank">java-给定字符串,删除开始和结尾处的空格,并将中间的多个连续的空格合并成一个。</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div> public class DeleteExtraSpace { /** * 题目:给定字符串,删除开始和结尾处的空格,并将中间的多个连续的空格合并成一个。 * 方法1.用已有的String类的trim和replaceAll方法 * 方法2.全部用正则表达式,这个我不熟 * 方法3.“重新发明轮子”,从头遍历一次 */ public static v</div> </li> <li><a href="/article/2117.htm" title="An error has occurred.See the log file错误解决!" target="_blank">An error has occurred.See the log file错误解决!</a> <span class="text-muted">Kai_Ge</span> <a class="tag" taget="_blank" href="/search/MyEclipse/1.htm">MyEclipse</a> <div>今天早上打开MyEclipse时,自动关闭!弹出An error has occurred.See the log file错误提示! 很郁闷昨天启动和关闭还好着!!!打开几次依然报此错误,确定不是眼花了! 打开日志文件!找到当日错误文件内容: --------------------------------------------------------------------------</div> </li> <li><a href="/article/2244.htm" title="[矿业与工业]修建一个空间矿床开采站要多少钱?" target="_blank">[矿业与工业]修建一个空间矿床开采站要多少钱?</a> <span class="text-muted">comsci</span> <div>        地球上的钛金属矿藏已经接近枯竭...........        我们在冥王星的一颗卫星上面发现一些具有开采价值的矿床.....        那么,现在要编制一个预算,提交给财政部门..</div> </li> <li><a href="/article/2371.htm" title="解析Google Map Routes" target="_blank">解析Google Map Routes</a> <span class="text-muted">dai_lm</span> <a class="tag" taget="_blank" href="/search/google+api/1.htm">google api</a> <div>为了获得从A点到B点的路劲,经常会使用Google提供的API,例如 [url] http://maps.googleapis.com/maps/api/directions/json?origin=40.7144,-74.0060&destination=47.6063,-122.3204&sensor=false [/url] 从返回的结果上,大致可以了解应该怎么走,但</div> </li> <li><a href="/article/2498.htm" title="SQL还有多少“理所应当”?" target="_blank">SQL还有多少“理所应当”?</a> <span class="text-muted">datamachine</span> <a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a> <div>转贴存档,原帖地址:http://blog.chinaunix.net/uid-29242841-id-3968998.html、http://blog.chinaunix.net/uid-29242841-id-3971046.html! ------------------------------------华丽的分割线-------------------------------- </div> </li> <li><a href="/article/2625.htm" title="Yii使用Ajax验证时,如何设置某些字段不需要验证" target="_blank">Yii使用Ajax验证时,如何设置某些字段不需要验证</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/Ajax/1.htm">Ajax</a><a class="tag" taget="_blank" href="/search/yii/1.htm">yii</a> <div>经常像你注册页面,你可能非常希望只需要Ajax去验证用户名和Email,而不需要使用Ajax再去验证密码,默认如果你使用Yii 内置的ajax验证Form,例如: $form=$this->beginWidget('CActiveForm', array(        'id'=>'usuario-form',&</div> </li> <li><a href="/article/2752.htm" title="使用git同步网站代码" target="_blank">使用git同步网站代码</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/crontab/1.htm">crontab</a><a class="tag" taget="_blank" href="/search/git/1.htm">git</a> <div>转自:http://ued.ctrip.com/blog/?p=3646?tn=gongxinjun.com   管理一网站,最开始使用的虚拟空间,采用提供商支持的ftp上传网站文件,后换用vps,vps可以自己搭建ftp的,但是懒得搞,直接使用scp传输文件到服务器,现在需要更新文件到服务器,使用scp真的很烦。发现本人就职的公司,采用的git+rsync的方式来管理、同步代码,遂</div> </li> <li><a href="/article/2879.htm" title="sql基本操作" target="_blank">sql基本操作</a> <span class="text-muted">蕃薯耀</span> <a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a><a class="tag" taget="_blank" href="/search/sql%E5%9F%BA%E6%9C%AC%E6%93%8D%E4%BD%9C/1.htm">sql基本操作</a><a class="tag" taget="_blank" href="/search/sql%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/1.htm">sql常用操作</a> <div>sql基本操作 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 蕃薯耀 2015年6月1日 17:30:33 星期一     &</div> </li> <li><a href="/article/3006.htm" title="Spring4+Hibernate4+Atomikos3.3多数据源事务管理" target="_blank">Spring4+Hibernate4+Atomikos3.3多数据源事务管理</a> <span class="text-muted">hanqunfeng</span> <a class="tag" taget="_blank" href="/search/Hibernate4/1.htm">Hibernate4</a> <div>Spring3+后不再对JTOM提供支持,所以可以改用Atomikos管理多数据源事务。Spring2.5+Hibernate3+JTOM参考:http://hanqunfeng.iteye.com/blog/1554251Atomikos官网网站:http://www.atomikos.com/   一.pom.xml <dependency> <</div> </li> <li><a href="/article/3133.htm" title="jquery中两个值得注意的方法one()和trigger()方法" target="_blank">jquery中两个值得注意的方法one()和trigger()方法</a> <span class="text-muted">jackyrong</span> <a class="tag" taget="_blank" href="/search/trigger/1.htm">trigger</a> <div>  在jquery中,有两个值得注意但容易忽视的方法,分别是one()方法和trigger()方法,这是从国内作者<<jquery权威指南》一书中看到不错的介绍 1) one方法     one方法的功能是让所选定的元素绑定一个仅触发一次的处理函数,格式为    one(type,${data},fn) &nb</div> </li> <li><a href="/article/3260.htm" title="拿工资不仅仅是让你写代码的" target="_blank">拿工资不仅仅是让你写代码的</a> <span class="text-muted">lampcy</span> <a class="tag" taget="_blank" href="/search/%E5%B7%A5%E4%BD%9C/1.htm">工作</a><a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a><a class="tag" taget="_blank" href="/search/%E5%92%A8%E8%AF%A2/1.htm">咨询</a> <div>这是我对团队每个新进员工说的第一件事情。这句话的意思是,我并不关心你是如何快速完成任务的,哪怕代码很差,只要它像救生艇通气门一样管用就行。这句话也是我最喜欢的座右铭之一。 这个说法其实很合理:我们的工作是思考客户提出的问题,然后制定解决方案。思考第一,代码第二,公司请我们的最终目的不是写代码,而是想出解决方案。 话粗理不粗。 付你薪水不是让你来思考的,也不是让你来写代码的,你的目的是交付产品</div> </li> <li><a href="/article/3387.htm" title="架构师之对象操作----------对象的效率复制和判断是否全为空" target="_blank">架构师之对象操作----------对象的效率复制和判断是否全为空</a> <span class="text-muted">nannan408</span> <a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84%E5%B8%88/1.htm">架构师</a> <div>1.前言。   如题。 2.代码。 (1)对象的复制,比spring的beanCopier在大并发下效率要高,利用net.sf.cglib.beans.BeanCopier Src src=new Src(); BeanCopier beanCopier = BeanCopier.create(Src.class, Des.class, false); </div> </li> <li><a href="/article/3514.htm" title="ajax 被缓存的解决方案" target="_blank">ajax 被缓存的解决方案</a> <span class="text-muted">Rainbow702</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a><a class="tag" taget="_blank" href="/search/Ajax/1.htm">Ajax</a><a class="tag" taget="_blank" href="/search/cache/1.htm">cache</a><a class="tag" taget="_blank" href="/search/%E7%BC%93%E5%AD%98/1.htm">缓存</a> <div>使用jquery的ajax来发送请求进行局部刷新画面,各位可能都做过。 今天碰到一个奇怪的现象,就是,同一个ajax请求,在chrome中,不论发送多少次,都可以发送至服务器端,而不会被缓存。但是,换成在IE下的时候,发现,同一个ajax请求,会发生被缓存的情况,只有第一次才会被发送至服务器端,之后的不会再被发送。郁闷。 解决方法如下: ① 直接使用 JQuery提供的 “cache”参数,</div> </li> <li><a href="/article/3641.htm" title="修改date.toLocaleString()的警告" target="_blank">修改date.toLocaleString()的警告</a> <span class="text-muted">tntxia</span> <a class="tag" taget="_blank" href="/search/String/1.htm">String</a> <div>  我们在写程序的时候,经常要查看时间,所以我们经常会用到date.toLocaleString(),但是date.toLocaleString()是一个过时 的API,代替的方法如下:   package com.tntxia.htmlmaker.util; import java.text.SimpleDateFormat; import java.util.</div> </li> <li><a href="/article/3768.htm" title="项目完成后的小总结" target="_blank">项目完成后的小总结</a> <span class="text-muted">xiaomiya</span> <a class="tag" taget="_blank" href="/search/js/1.htm">js</a><a class="tag" taget="_blank" href="/search/%E6%80%BB%E7%BB%93/1.htm">总结</a><a class="tag" taget="_blank" href="/search/%E9%A1%B9%E7%9B%AE/1.htm">项目</a> <div>项目完成了,突然想做个总结但是有点无从下手了。 做之前对于客户端给的接口很模式。然而定义好了格式要求就如此的愉快了。 先说说项目主要实现的功能吧 1,按键精灵 2,获取行情数据 3,各种input输入条件判断 4,发送数据(有json格式和string格式) 5,获取预警条件列表和预警结果列表, 6,排序, 7,预警结果分页获取 8,导出文件(excel,text等) 9,修</div> </li> </ul> </div> </div> </div> <div> <div class="container"> <div class="indexes"> <strong>按字母分类:</strong> <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a> </div> </div> </div> <footer id="footer" class="mb30 mt30"> <div class="container"> <div class="footBglm"> <a target="_blank" href="/">首页</a> - <a target="_blank" href="/custom/about.htm">关于我们</a> - <a target="_blank" href="/search/Java/1.htm">站内搜索</a> - <a target="_blank" href="/sitemap.txt">Sitemap</a> - <a target="_blank" href="/custom/delete.htm">侵权投诉</a> </div> <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved. <!-- <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>--> </div> </div> </footer> <!-- 代码高亮 --> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script> <link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/> <script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script> </body> </html>