问题描述:
在ubuntu22.04上编译autoware autoware_carla_interface库时,报setup.py install is deprecated命令已弃用stderr
在ubuntu22.04上编译autoware autoware_carla_interface库时,报setup.py install is deprecated命令已弃用stderr
在ubuntu22.04上编译autoware时,报TypeError: canonicalize_version() got an unexpected keyword argument ‘strip_trailing_zero’错误
1.编写一个简单的c .so
skimage即是Scikit-Image。基于python脚本语言开发的数字图片处理包,比如PIL,Pillow, opencv, scikit-image等。 PIL和Pillow只提供最基础的数字图像处理,功能有限;opencv实际上是一个c++库,只是提供了python接口,更新速度非常慢。scikit-image是基于scipy的一款图像处理包,它将图片作为numpy数组进行处理,与matlab一样。
为什么会用AC自动机? 如果你想知道一篇文章有没有你要过滤的敏感词,怎么办? 不可能用正则一个个的匹配吧? 敏感词超过300个之后,用Trie来构建模式树 (字典树)的速度优势相当的明显… …
特别说下,trie图也是一种DFA,可以由trie树为基础构造出来,对于插入的每个模式串,其插入过程中使用的最后一个节点都作为DFA的一个终止节点。
如果要求一个母串包含哪些模式串,以用母串作为DFA的输入,在DFA 上行走,走到终止节点,就意味着匹配了相应的模式串。
ps: AC自动机是Trie的一种实现,也就是说AC自动机是构造Trie图的DFA的一种方法。还有别的构造DFA的方法…
不扯淡了,我们后端都是python写的,python的ahocorasick模块跟我们的业务不太匹配,问题是这样的 ! 如果你的服务是用来做敏感词匹配,也就是说所有文章里面只要含有一个关键词,那就说明匹配了。 但是我们的业务是文章中的所有能匹配到的关键词都一一的抽取出来。 我想有些朋友可能还不太明白,那么我举个例子, 如果我的关键词里面有宝马和马,那么用python的ahocorasick库只会得到宝马,而不会得到马。 问题是处在马这个字节是在宝马的链条里面的。 如何避开这个问题,我们也懒得自己重写了,已经有人给出了解决的模块。 已经测试完成,并上线使用了。
安装简单,直接pip install esmre
import esm
index = esm.Index()
index.enter("宝马")
index.enter("马")
index.enter("奔驰")
index.enter("保时捷")
index.fix()
index.query("哎呀,今天在楼下看到了宝马,我老家倒是有养马的,以前的邻居有个奔驰,不对是保时捷,大爷的,都是马")
再来一个完整的例子. 后续有时间我会把ac自动机的服务集成到rpc服务里面,然后用docker打包。
#coding:utf-8
import esm
index = esm.Index()
with open('keyword.config','r') as f:
for i in f.readlines():
index.enter(i.strip())
index.fix()
str = """
head&shoulders海飞丝Hershey‘s
Loreal欧莱雅LUX2
力士
L’OREALMagic2
美即
MysteryCity
谜城
NO.1BABY2
RESIN
SANXIAO
SHISEIDO FINE TOILETRY2
SKII美之匙
Tao yu tang2
淘雨堂
whoo倍加洁
卡尔林奈
娇韻诗
德国帮宝适
Perfect puff2
See Young2
落健
高夫
"""
data = index.query(str)
print data
测了几天,性能还是可以的,500KB的文章,6000多个关键词,消耗的时间在0.002左右,相比ahocorasick一点都不差的。 观察了下,esmre是没有发现内存异常泄露等问题。
[2015-06-12 23:34:01,043] INFO extractor "Get keywords takes 0.0003 seconds"
[2015-06-12 23:34:01,069] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:01,178] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:02,372] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:02,386] INFO extractor "Get keywords takes 0.0012 seconds"
[2015-06-12 23:34:02,631] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:03,656] INFO extractor "Get keywords takes 0.0021 seconds"
[2015-06-12 23:34:03,744] INFO extractor "Get keywords takes 0.0001 seconds"
[2015-06-12 23:34:03,785] INFO extractor "Get keywords takes 0.0001 seconds"
[2015-06-12 23:34:03,910] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:04,031] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:05,004] INFO extractor "Get keywords takes 0.0035 seconds"
[2015-06-12 23:34:05,579] INFO extractor "Get keywords takes 0.0055 seconds"
[2015-06-12 23:34:05,602] INFO extractor "Get keywords takes 0.0005 seconds"
[2015-06-12 23:34:05,662] INFO extractor "Get keywords takes 0.0010 seconds"
[2015-06-12 23:34:06,125] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:06,299] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:06,404] INFO extractor "Get keywords takes 0.0003 seconds"
[2015-06-12 23:34:07,396] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:07,595] INFO extractor "Get keywords takes 0.0004 seconds"
[2015-06-12 23:34:08,725] INFO extractor "Get keywords takes 0.0015 seconds"
[2015-06-12 23:34:09,504] INFO extractor "Get keywords takes 0.0004 seconds"
[2015-06-12 23:34:09,515] INFO extractor "Get keywords takes 0.0005 seconds"
[2015-06-12 23:34:10,650] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:11,206] INFO extractor "Get keywords takes 0.0003 seconds"
[2015-06-12 23:34:12,298] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:12,319] INFO extractor "Get keywords takes 0.0001 seconds"
[2015-06-12 23:34:13,547] INFO extractor "Get keywords takes 0.0006 seconds"
[2015-06-12 23:34:13,853] INFO extractor "Get keywords takes 0.0005 seconds"
2.在api初始化时保持数据库长链接;并且用线程每2分钟遍历一次所有的表并count一次
import sys
import time
import pymongo
import json
import log
import traceback
import threading
//库名test,表名test_table
server_list = ['test-mongos.all.serv:6365' for i in range(8)]
conn_str = "mongodb://test:123456@" + ",".join(server_list) + "/test"
print conn_str
conn = pymongo.MongoClient(conn_str)
test = conn.test
def load_cache(){
#load cache
try:
table_names_cache = test.collection_names()
for tb in table_names_cache:
print tb, test[tb].count()
except:
traceback.print_exc()
log.warn("acl data load failed")
# threading reflash
bg_job = threading.Timer(120, load_acl_data, ()) #120 seconds
bg_job.start()
}
#query
start_time = time.time()
condition = {"id": "abc"}
doc_iter = test['test_table'].find(condition, {"_id": 0}).batch_size(15).limit(1)
docs = list(doc_iter.max_time_ms(200000)) #200000ms
end_time = time.time()
print "use time:" + str(end_time - start_time)
你会发现使用主键或唯一索引进行增删改查时,调这个api的平响会是你直接调原生lib读写耗时的1/10 – 1/20左右(平响20-50ms=>3-5ms),原理应该就是count请求导致了主键和唯一索引短时间内被cache,此时增删改定位数据位置时用到了内存中的索引cache所以速度变快。
(注:mongo集群需要有比较充沛的内存)
yan 20170815 01:33
Gunicorn 绿色独角兽 是一个Python WSGI UNIX的HTTP服务器。这是一个pre-fork worker的模型,从Ruby的独角兽(Unicorn )项目移植。该Gunicorn服务器大致与各种Web框架兼容,只需非常简单的执行,轻量级的资源消耗,以及相当迅速。
使用python做了些很有趣的代码封装,希望能在php+nginx里调用,因为使用了第三方库的原因很难移植,除了用php执行python命令调用外,有什么更好的办法吗?
python发送post请求代码示例:
import sys
import httplib, urllib
import traceback
def post(params):
'发送post请求'
result = {'status':500, 'reason':'', 'response':'', 'headers':''}
httpClient = None
try:
data = urllib.urlencode(params['data'])
httpClient = httplib.HTTPConnection(params['hostname'], params['port'], timeout=30)
if params.has_key('header'):
httpClient.request("POST", params['path'], data, params['header'])
else:
httpClient.request("POST", params['path'], data)
response = httpClient.getresponse()
result['status'] = response.status
result['reason'] = response.reason
result['response'] = response.read()
result['headers'] = response.getheaders() #获取头信息
except:
self.writelog("error", 'post fail! [' + params['path'] + '][' + data + ']\n' + self.get_trace())
finally:
if httpClient:
httpClient.close()
return result
def get_trace():
'获得异常栈内容'
try:
errmsg = "Traceback (most recent call last):\n "
exc_type, exc_value, exc_tb = sys.exc_info()
for filename, linenum, funcname, source in traceback.extract_tb(exc_tb):
errmsg += " File \"%-23s\", line %s, in %s() \n\t %s \n" % (filename, linenum, funcname, source)
errmsg += str(exc_type.__name__) + ": " + str(exc_value)
#traceback.print_exc()
except:
errmsg = ''
return errmsg
#测试post请求
params = {}
params['hostname'] = "test.yanjingang.com"
params['port'] = 80
params['path'] = "/api.php"
params['data'] = {'t': 25}
params['timeout'] = 30
params['header'] = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
res = self.post(params)
print res['status']
print res['response']
执行结果:
class TestBase:
test={}
def __init__(self, key):
self.test[key] = 1
def get(self):
return self.test
class TestA(TestBase):
def get(self):
return self.test
class TestB(TestBase):
def get(self):
return self.test
key = ‘aaa’
tb = TestA(key)
print tb.get()
key = ‘bbb’
tb = TestB(key)
print tb.get()
我想当然的认为输出结果会是:
{‘aaa’: 1}
{‘bbb’: 1}
没想到实际输出的是:
{‘aaa’: 1}
{‘aaa’: 1, ‘bbb’: 1}
也就是说,两个不同的子类的不同实例之间,类的属性竟然是打通的。。。查了一下后发现python的逻辑是这样的:在定义类属性的位置声明的属性是类属性,改变它的值会影响所有继承它的类实例;如果不声明直接在函数中使用self.xxx的属性,是实例属性,生命周期只存在于当前实例中,对当前实例外没有任何影响。
也就是上边的badcase解决方法是:
class TestBase:
def __init__(self, key):
self.test={}
self.test[key] = 1
def get(self):
return self.test
class TestA(TestBase):
def get(self):
return self.test
class TestB(TestBase):
def get(self):
return self.test
key = ‘aaa’
tb = TestA(key)
print tb.get()
key = ‘bbb’
tb = TestB(key)
print tb.get()
输出结果:
{‘aaa’: 1}
{‘bbb’: 1}
Protocol Buffers,简称protobuf或pb,是Google公司开发的一种数据描述语言,类似于XML和JSON能够将结构化数据序列化用于数据存储、通信协议等方面。目前官方支持C++、JAVA、Python等三种编程语言。
与XML和JSON相比,protobuf在配置时将数据key映射为递增数字,使用二进制传输,并能够根据schema自动生成各语言的打包、解析回kv的代码,非常方便各语言数据互通,且有以下优点:
1. 数据文件只需原来的1/10至1/3 #相同的数据,大小只有json的1/10
2. 解析速度是原来的20倍至100倍
3. 通过递增数字做key传输value,减少了二义性,在接口发生变化时完全像后兼容
4. 非常容易自动生成各语言中使用的数据访问类,将数据key根据schema自动转回易理解的英文key
protobuf不是用来替代json和xml的,它最初的目的是为了更小的带宽占用、更快的传输速度,所以使用数据key+二进制传输,也产生了一些缺点:
1. 对人不可读。(适合加密数据传输)
2. 不能发给web浏览器,比如js无法处理这种数据。(适合c、java、python语言开发的程序间共享数据)
3. 开发适配成本高,不适合schema经常变的场景。(适合公司内部各产品间相对通用稳定的协议通信)
前提:需要gcc, gcc-c++, make, build等编译环境
yum -y install gcc gcc-c++ libstdc++-devel make build
# proto2用下边这个包
wget https://blog.yanjingang.com/wp-content/uploads/2016/09/protobuf-2.5.0.tar.gz
# proto3直接用最新release版即可:https://github.com/protocolbuffers/protobuf/releases
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.11.4/protobuf-all-3.11.4.tar.gz
*注:使用python3+proto2时,python的protobuf库版本兼容性问题能把人折麽死(proto2主要为python2开发,最后一次发布是14年,对python3的兼容性极差),建议别在这个事情上浪费时间了,如果当前用的proto2,要么升级proto版本到3,要么降python版本到2。
tar zxvf protobuf-3.11.4.tar.gz
cd protobuf-3.11.4
./configure
make
make check
make install
protoc --version
>>libprotoc 3.11.4
cd ./python
python setup.py build
python setup.py test
python setup.py install
python
>>>import google.protobuf
# 配置test.proto syntax="proto3"; package test.abc; //Test message Test { string name = 1; uint32 speed = 2; State state = 3; float time = 5; bytes content = 6; enum State { STATE_OFF = 0; STATE_STANDBY = 1; STATE_READY = 2; } }; # 生成pythhon类
protoc --python_out=./ ./test.proto #--python_out=生成的python文件输出路径 对应的proto文件
from test_pb2 import Test
test = Test()
test.name='A'
# 转pb
msg = test.SerializeToString() #序列化这个message和以字符串的方式返回。 注意,这是二进行字节,不是一个文本; 我们只使用str类型作为一个方便的容器。
print(msg)
# 解析pb
test.ParseFromString(msg) #从给出的字符串中解析一条message
print(test)
如有前端js解析proto的需求,可以使用 protobuf.js 。
参考:
在Python中使用protocol buffers参考指南
pip 是一个Python包管理工具,主要是用于安装 PyPI 上的软件包,可以替代 easy_install 工具。
Python 读取写入配置文件很方便,可使用内置的 configparser 模块,位置在 “python27/lib/configparser.py”,该模块支持读取类似ini/conf格式的配置文件。