日期: 2021 年 5 月 6 日

自从有了阿里云就不需要云计算运维工程师了?

是不是有了阿里云,对于运维工程师的需求就减少了呢?大家也知道有个耳熟能详的词语叫DevOps。这也说明了一个问题:云计算厂商把IT基础设施运营起来了,带来了一个重大的变化:企业内部并不需要单纯的运维工程师了。为什么呢?一是因为DevOps的发展,二是因为云计算带来的*大便利使得很多运维工作被大大简化。

举例来说,*大多数尚未建立完备开发体系的公司,它的开发工程师就可以通过RAM授权的子账号,甚至主账号进入云的控制台修改关键云资源配置,比如对象存储Bucket的修改。

因此,由于云的分布式的变化,每一个工程师都可以通过API或者控制台,快速的改变云的现状,包括配置信息的变更。这使得传统的运维工作离散化了。某种程度上说,不是不需要运维工程师,而是人人皆运维。在这样的大背景下,传统的运维工程师又何去何从呢?他们的职业发展也面临着巨大的变化。传统意义上的运维工程师的主要工作,我们经常开玩笑说是搬箱子,插网线和装系统三大件。而今天面对云,这三件事情都不用做了,因为你使用ECS镜像服务器就装好了,甚至你都不需要自己安装MySQL,直接使用RDS就够了。

云计算,虚拟化,确实给接入带来了很多的便利。但是,也只是从需要一个团队变成了需要一个人,而不是完全傻瓜的接入。但是,云产品的选型,实例的维护,都需要一个懂的人来做的。运维是一个加强的技术支持,可以避免很多坑。

因此传统意义上运维工程师本身知识结构面临着更新,从传统意义上运维工程师要变成企业内部的云管理员或者成为企业内部云架构师,应该往这个方向去转变。运维同样规模的系统,对基础运维的人数要求低了,但平台以及平台之上的运维需求大了,能力要求高了。从宏观层面上看IT系统总体需求量增大,所以总体上来说对高端运维人数的需求量是增加了。意味着,传统运维的人如果不学习就会被淘汰,坚持学习就总会有机会!

云计算运维累不累_云计算运维工程师前景怎么样?

随着云计算的兴起,运维工程师一职也逐渐火爆起,但我在这跟想转linux运维的朋友来说下真心话,希望对我的帖子能够手下留情。

LZ有将近8年的工作经验,到今天已经经历了4年互联网公司,2家上

市在中国国内排名前10的手游公司,今天是我提出辞职的一天,我放弃了在公司内部正在转高级I的流程机会,意味着我放弃了月薪固定14K,弹打卡(全天不要求考勤),每个月1000多块的车补(高级1以上),连续2年的年终*绩效在B+以上,(至少3.5个月以上),当然我明白这些待遇对于BAT的同学们来说根本不值一提,但是我仍然想对那些看着linux起薪高,入门简单的同学说一句:这个领域我不建议大家尝试!

首先,我必须强调从事linux运维和学习linux知识是根本两回事,假设你,那

你一定

从事的是一份职业

要对你的预期,5年,10年有长期的规划,我在SF也带过不少新人,很多都是985硕士毕业,每当问道:linux运维薪水*高到底能拿多少这个问题时候,我只有一句回答:任何职位的高薪,一定是社会所承认的价值所在!

08年到10年,我相信在深圳任何linux运维工资都略高于java开发,这是事实!13年开始,linux运维技术进行革命的变更,云计算的出现,

docke容器技术,zabbix监控….各种自动化运维工具,.这些技术在蚕食linux运维朋友们一点点的剩余价值。

也许有人说:我认识某某,他只做了一年linux运维,就拿到一万,是的,我承认。如果你来我来我们公司我们项目组,只需要半年,半年可以让你成长到在深圳月薪10K的地步,可是没有职业的预期有意义吗?

这个社会永远是知识的竞争,10年时候,你说出10个以上的apache配置参数,你一定可以被面试官认为是牛人,12年时候人家面试只考nginx了,11年,你可以说出全公司将近100台服务器都是自己用icinga+nagios部署的监控,可是13年以后再去面试,任何创业公司都会说:监控这块我们都是用zabbix。。。。

太多的例子已经说明linux运维无法稳定的发展,不要说IT从事的工作要永远学习,我敢说linux下面所有的服务全部精通的人,在这个社会上都找不到几个,你在手游公司精通了tomcat,你来金融公司人家容器是jboss,这仅仅是一个java应用而已!

linux运维需要的知识面实在太广了,我说这么多没别的意思,我这样的普通人是注定无法到达大神的地步,辞职以后,我已经决定专注python,今年是我满30岁的一年,我放弃了linux领域所有的发展,用8年进行试错,我不能说服任何同学同意我的观点,但是我愿意和大家共勉

利益相关:个人站长、35互联A级代理、百度开放云用户、阿里云用户、百度员工。

入职华为云计算工程师值得嘛?

入职华为云计算工程师值得嘛?
无论是从公司的成长还是个人成长来看,入职华为云计算工程师都是值的!
理由一:华为云在中国云厂商中增速*快
市场研究公司Canalys日前发布了2019年第四季度中国公有云服务市场报告。报告显示,阿里云排名*,市场份额环比上涨至46.4%。同期,腾讯云市场份额18%,百度云份额8.8%。
而华为云显然在2019年中国公有云市场都排不上号,被归为“others”一列。
但是,今年以来,华为云可谓在公有云市场掀起一番腥风血雨。
华为云产品竞争力不断提升,基础设施规模、付费用户数等高速增长,根据Canalys的数据显示,2020年上半年华为云在中国云厂商中增速*快,位列中国公有云市场(IaaS+PaaS)第三,已连续五个季度在中国TOP云厂商中增速*快。
公司的快速成长,自然能够给到这艘快速前进的大船上的个人足够的磨练机会和丰厚的薪资待遇。

理由二:华为云工程师更有可能获得更好的薪资待遇
后起的优秀公司往往会开比行业龙头更多的薪资待遇来吸引优秀的人才。Pdd和某跳动公司就是很好的例子。云市场行业亦是如此。
阿里云占据国内云市场份额*已经好几年了,但是截至到2019年低,阿里云还处在亏损运营种。为了控制成本,对下面的员工自然也是大方不起来。
火爆全文的腾讯云发iPhone,爆出云团队有的团队年终*人均20w
从19年底的年终*对比,可以明显看出腾讯云对待员工的待遇明显是好于行业老大阿里云的。
选择华为云,自然也不会在薪资待遇上吃亏。
华为一直强调以奋斗者为本,什么意思呢?就是你干的多干的好,自然也*励的多。华为19年火爆全网的发*金事件多多少少也反映了这个情况。
华为云正处在急需用人的关键环节,云计算工程师加入一个快速成长且有明确*惩机制的公司自然是一个不错的选择。

列式存储与行式存储

以前不是特别明白列式存储和行式存储到底有什么区别,对于突然蹦出来的BigTable、HBase、Cassandra这些NoSQL数据库凭什么比MySQL集群,Oracle在分析存储上的强大?思来可以这样说说。

A. 存储

传统RDBMS以行单位做数据存储(字段为空则赋值为‘NULL’),列式存储数据库以列为单位做数据存储。如下:

%title插图%num

%title插图%num

对于列式存储来说,一行数据包含一个列或者多个列,每个列一单独一个cell来存储数据。而行式存储,则是把一行数据作为一个整体来存储。

另外一个不得不提的是,列式存储天生就是适合压缩,因为同一列里面的数据类型基本是相同,笔者在之前使用普通的gzip压缩,200MB的字符串数据,经过压缩之后只剩下8MB。当然gzip并不属于增量压缩,我们可以选择增量压缩的方式来满足一些数据的随机查找。

B.  查询

从查询来说,行式存储比较适合随机查询,并且RDBMS大多提供二级索引,在整行数据的读取上,要优于列式存储。但是,行式存储不适合扫描,这意味着要查询一个范围的数据,行式存储需要扫描整个表(因为这些记录不是顺序存储的),在索引建立不当的情况下,查询大表(千万数据)简直是噩梦。

列式存储,*早接触的可能不是所谓的BigTable,大多数以前的数据仓库都是采用列式存储。列式存储一般行KEY,列KEY(不是列值)都是顺序存储,比如我要查询一个时间段里面,某个值的出现频率,我可能只需要涉及到两个列。

在分析上,列式存储要优于行式存储,列式存储的数据库一般情况下也强烈建议用户按需查找,而不是整行数据去获取。列式存储在这方面减少了IO的压力。

C. 结语

没有说谁比谁更优,在正真实战的情况,考虑实际情况。比如传统的RDBMS提供ACID原子操作和事务,在大多数列式存储数据库上是不具备的,大多数列式存储数据库对分布式支持友好。

需要知道的是,列式存储以及行式存储在查询和存储上的本质,在技术选型上多点筹码。

什么是列式数据库?列式数据库是以列相关存储架构进行数据存储的数据库。卢东明认为数据库发展已经到了一个新阶段,数据库市场需要细分,行式数据库不再满足所有的需求,而有很多需求需要通过内存数据库和列式数据库解决,列式数据库在数据分析、海量存储、BI这三个领域有自己独到。

5 年内可能会发生以下变化:

大多数数据仓库将以列模式存储

大多数 OLTP 数据库将可能是内存数据库 (IMDB),或完全驻留在内存内

大多数大型数据库服务器将通过集群方式进行横向扩展

很多数据收集和报告问题将由没有任何形式图式的数据库解决。

传统的行式数据库,是按照行存储的,维护大量的索引和物化视图无论是在时间(处理)还是空间(存储)方面成本都很高。而列式数据库恰恰相反,列式数据库的数据是按照列存储,每一列单独存放,数据即是索引。只访问查询涉及的列,大大降低了系统I/O,每一列由一个线来处理,而且由于数据类型一致,数据特征相似,*大方便压缩。

*后卢东明很务实的指出,没有万能的数据库,Sybase IQ也并非万能,只不过给DBA们的工具箱里提供更多的选择,DBA需根据自己的应用场景自行选择。

在数据仓库领域,列式数据库和传统的行式数据库有何差别呢?列式数据库和行式数据库的拥护者均认为结合这两种技术的混合数据库是个不错的想法。

行式数据库擅长随机读操作,列式数据库则更擅长大批量数据量查询,而混合数据库则试图同时包含这两种技术的优点,在灾难恢复环境中,数据要么按列式存储,要么按行式存储。

我认为未来将是列式数据库的天下,行数据库和混合型数据库都将渐渐消亡,原因如下:数据增长速度很快,对存储设备(主内存和SSD)的需求也将不断上升,随着主内存和SSD中压缩列所占百分比的提高,列式数据库随机读的弱点反而变成了优点,这样列式数据库不管是应付联机事务处理,还是大批量更新或大型报表需要执行的复杂查询都能应付自如。对于更新操作而言,列式数据库和行式数据库在这方面已经没有多大差距了,因为大部分更新操作只会影响到一行中的一到三列(字段),同时,大部分更新操作影响的是*近的数据,因此主内存/SSD缓存中数据会越来越多。对于插入和删除操作而言,先在内存中快速更新索引,然后再写入磁盘,这意味着在I/O密集型情况下也不会有明显的性能下降。对在线备份而言,按列存储方法压缩数据后备份时间窗口将会更短。

对今天的数据仓库而言,列式数据库的性能和传统行数据库相比,根本不在一个数量级上,列式数据库已经得到了广泛的认可和使用(Sybase IQ已经有十年历史,也出现了一些新兴列式数据库公司,如Vertica),数据库巨人Oracle也按捺不住,在其Exadata数据库机中也加入了按列存储选择,IBM则提供了一个列式专用设备,它可以确定什么数据该按列存储,什么数据该按行存储,然后将事务分流到相应的设备。

列式数据库

维基百科,自由的百科全书

列式数据库是以列相关存储架构进行数据存储的数据库,主要适合与批量数据处理和即席查询。相对应的是行式数据库,数据以行相关的存储体系架构进行空间分配,主要适合与小批量的数据处理,常用于联机事务型数据处理。

[编辑]描述

数据库以行、列的二维表的形式存储数据,但是却以一维字符串的方式存储,例如以下的一个表:

EmpId Lastname Firstname Salary
1 Smith Joe 40000
2 Jones Mary 50000
3 Johnson Cathy 44000

这个简单的表包括员工代码(EmpId), 姓名字段(Lastname and Firstname)及工资(Salary).

这个表存储在电脑的内存(RAM)和存储(硬盘)中。虽然内存和硬盘在机制上不同,电脑的操作系统是以同样的方式存储的。数据库必须把这个二维表存储在一系列一维的“字节”中,又操作系统写到内存或硬盘中。

行式数据库把一行中的数据值串在一起存储起来,然后再存储下一行的数据,以此类推。

1,Smith,Joe,40000;2,Jones,Mary,50000;3,Johnson,Cathy,44000;

列式数据库把一列中的数据值串在一起存储起来,然后再存储下一列的数据,以此类推。

1,2,3;Smith,Jones,Johnson;Joe,Mary,Cathy;40000,50000,44000;

这是一个简化的说法。

列式数据库的代表包括:Sybase IQParAccelSand/DNA Analytics和 Vertica

Sybase IQ: 知道IQ跟其它的关系型数据库相比,它的主要特征是什么?包括查询快、数据压缩比高、Load快,但是插入更新慢,不太适合数据老是变化,它是按列存储的。这时候你就知道它适做DSS(决策支持系统),数据集市,数据仓库,它不适合OLTP。适合OLAP 。

列式数据库的优点:
数据压缩比高,正因为同一类型的列存储在一起。
简化数据建模的复杂性。
由于查询需要读取的blocks少,速度更快。
BI的优秀选择。

阿里云发布vSphere虚拟机备份服务 ,网络带宽有限条件下依然能有效保护数据

常见虚拟机备份技术的挑战

传统常见的虚拟机备份方式是把虚机机当做单独的主机,在每台虚拟机上安装备份软件,然后备份到本地的存储,这种方案可以用在虚拟机数目不大的环境,当虚拟机规模很大的时候,这种备份方案的部署管理就变得非常复杂,不仅影响运维效率,更可能导致备份作业失败,数据得不到有效的保护。

传统备份方案主要的问题:

 备份管理复杂,需要管理多个独立的备份客户端以及相应的备份策略;

 需要部署和维护本地备份存储,存储空间扩容周期长 ;

 缺乏有效的重复数据删除和压缩能力,成本较高;

 生产环境和备份设备在相同的机房,一旦发生灾难情况,生产环境数据和备份数据同时丢失。

以上这些问题长期困扰着备份管理员,混合云备份HBR for vSphere简化备份和恢复策略,减少人工操作,让备份管理员从复杂的日程维护中解放出来。混合云备份提供了vSphere虚拟机备份的完整解决方案, 支持VAPP一键部署,无需部署云下的备份服务器和备份设备,数据经过集成的全局客户端可变长重删后,快速安全高效地备份上云。
**
HBR for vSphere的使用场景**

这里写图片描述

在客户数据中心只需要部署HBR备份VAPP就可以方便地备份VMware ESXi上的虚拟机,借助公网或者专线就可以将vSphere环境和阿里云打通,阿里云备份库的高可用性,云备份库自带的多副本功能,确保客户备份数据的安全可靠。
这里写图片描述

混合云备份采用CBT(Change Block Tracking)技术,实现了更快的数据备份和恢复,相对于全量备份时将VMDK的全部数据保存到备份库, 基于CBT的增量备份只需要保存上次备份后发生了变化的数据块。VMware ESXi为每个开启了CBT功能的虚拟磁盘都创建了ctk文件,用于保存变化块的元数据。混合云备份基于CBT技术只传输变化的数据块,并且在备份的过程中可以和上一次备份的索引快速合并形成全量备份,这样可以显著提高备份还原效率。

HBR for vSphere的优势

快速备份:采用CBT技术只备份增量数据,可以有效缩短备份窗口
降低使用成本:支持不同的虚拟机镜像备份到同一个备份库,虚拟机镜像之间的重复数据非常多,高效的重删压缩算法可以大幅减少所需的备份库存储空间
运维简单: 无需管理备份服务器和备份库,备份客户端安装配置简单,备份*速上云,云端集中监控
阿里云此次推出的HBR for vSphere提供了端到端虚拟机备份、恢复和云端管理功能,让客户在整个虚拟机生命周期中更好的保护虚拟机。

朴素贝叶斯-使用训练样本量来画学习曲线

朴素贝叶斯-使用训练样本量来画学习曲线

#绘制学习曲线
import numpy as np
import matplotlib.pyplot as plt
from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import ShuffleSplit
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.tree import DecisionTreeClassifier as DTC
from sklearn.linear_model import LogisticRegression as LR
from sklearn.datasets import load_digits
from sklearn.model_selection import learning_curve
from time import time
import datetime
#定义一个绘制学习曲线的函数
def plot_learning_curve(estimator,title,X,y,
ax,#选择子图
ylim=None,#设置纵坐标范围
cv=None,#交叉验证
n_jobs=None#设定线程
):

train_sizes,train_scores,test_scores=learning_curve(estimator,X,y,cv=cv,n_jobs=4)
ax.set_title(title)
if ylim is not None:
ax.set_ylim(*ylim)
ax.set_xlabel(“Training examples”)
ax.set_ylabel(“Score”)
ax.grid()#显示网格作为背景
ax.plot(train_sizes,np.mean(train_scores,axis=1),’o-‘,color=’r’,label=”Training sore”)
ax.plot(train_sizes,np.mean(test_scores,axis=1),’o-‘,color=’g’,label=”Test sore”)
#因为是分成50份,所以会有50个结果,所以要取均值,另外,o-表示以点横的样子画图
ax.legend(loc=”best”)
return ax

#把数据集分成50分,其中百分之20是测试集,
digits=load_digits()
X,y=digits.data,digits.target
title=[“Naive Bayes”,”DecisionTree”,”SVM,RBF kernel”,”RandomForest”,”Logistic”]
model=[GaussianNB(),DTC(),SVC(gamma=0.001),RFC(n_estimators=50),LR(C=0.1,solver=”lbfgs”)]
cv=ShuffleSplit(n_splits=50,test_size=0.2,random_state=0)

fig,axes=plt.subplots(1,5,figsize=(30,6))#设置多个子图,一行5列
#函数返回一个figure图像和子图ax的array列表

fig, axes = plt.subplots(1,5,figsize=(30,6))
for ind,title_,estimator in zip(range(len(title)),title,model):
times = time()
plot_learning_curve(estimator, title_, X, y,
ax=axes[ind], ylim = [0.7, 1.05],n_jobs=4, cv=cv)
print(“{}:{}”.format(title_,datetime.datetime.fromtimestamp(time()-
times).strftime(“%M:%S:%f”)))
plt.show()#注意缩进

决策树为什么快呢:没有计算所有特征的信息熵,而是是从中随机选择的几个,随着样本量增大会越来越慢
朴素贝叶斯:再很少的样本上得到不错的效果,随着样本量增大会比决策树跑的更快一些,
因为当特征很大的时候,决策树是万万不敢只选择几个特征进行建模的,但是,朴素贝叶斯仍然会有不错的结果
逻辑回归为什么慢:受到的特征过多,稀疏矩阵的原因,再线性上比较快
再训练集上:其他算法都是百分之百,但是贝叶斯为什么达不到百分之百,而且还在下降,说明贝叶斯不是一个很好的分类器,而且随着样本量增加,需要学习的东西越来越多,贝叶斯学习能力下降
再过拟合方面:过拟合就是训练集上的表现比测试集上的表现好很多的现象,也就是两条线的差异
总之,如果追求概率的话,再能使用逻辑回归的情况下都会使用逻辑回归,因为当数据量比较大的时候,贝叶斯测试结果已经到了*限,没有调参的空间。数据高维,很多的时候,贝叶斯很快

webrtc android 打包成aar

webrtc android 打包成aar

我的环境:webrtc*新的, ubuntu20.04, python2.7

webrtc android 打包成aar,执行 tools_webrtc/android/release_aar.py –verbose –build-dir out/aar_release  会出现下面一些错误:

Traceback (most recent call last):
File “tools_webrtc/android/release_aar.py”, line 31, in <module>
import requests
ImportError: No module named requests
错误明显是没安装requests,

需要对 src/gedit tools_webrtc/android/release_aar.py 做修改,而且支持python2.7,需要安装pip,再用pip 安装requests,具体怎么安装网上查找实现,

安装好requests后,再执行上面的命令出现如下错误:

INFO:root:Releasing AAR version 1.0.33829 with hash 448d18b18d57871d1030fc8748b34250e48be385
Traceback (most recent call last):
File “tools_webrtc/android/release_aar.py”, line 307, in <module>
sys.exit(main())
File “tools_webrtc/android/release_aar.py”, line 303, in main
ReleaseAar(args.use_goma, args.skip_tests, args.publish, args.build_dir)
File “tools_webrtc/android/release_aar.py”, line 255, in ReleaseAar
‘Environment variables BINTRAY_USER and BINTRAY_API_KEY ‘
Exception: Environment variables BINTRAY_USER and BINTRAY_API_KEY must be defined.
这是需要你验证用户信息,因为发布到api.bintray.com上去需要验证用户信息,但我们现在用不上,解决方法是,修改release_aar.py ,把其他没用的注释掉即可,修改如下:

#!/usr/bin/env python

# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
“””Script for publishing WebRTC AAR on Bintray.
Set BINTRAY_USER and BINTRAY_API_KEY environment variables before running
this script for authentication.
“””

import argparse
import json
import logging
import os
import re
import shutil
import subprocess
import sys
import tempfile
import time

SCRIPT_DIR = os.path.dirname(os.path.realpath(sys.argv[0]))
CHECKOUT_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, os.pardir, os.pardir))

sys.path.append(os.path.join(CHECKOUT_ROOT, ‘third_party’))
import requests
import jinja2

sys.path.append(os.path.join(CHECKOUT_ROOT, ‘tools_webrtc’))
from android.build_aar import BuildAar

ARCHS = [‘armeabi-v7a’, ‘arm64-v8a’, ‘x86’, ‘x86_64’]
MAVEN_REPOSITORY = ‘https://google.bintray.com/webrtc’
API = ‘https://api.bintray.com’
PACKAGE_PATH = ‘google/webrtc/google-webrtc’
CONTENT_API = API + ‘/content/’ + PACKAGE_PATH
PACKAGES_API = API + ‘/packages/’ + PACKAGE_PATH
GROUP_ID = ‘org/webrtc’
ARTIFACT_ID = ‘google-webrtc’
COMMIT_POSITION_REGEX = r’^Cr-Commit-Position: refs/heads/master@{#(\d+)}$’
API_TIMEOUT_SECONDS = 10.0
UPLOAD_TRIES = 3
# The sleep time is increased exponentially.
UPLOAD_RETRY_BASE_SLEEP_SECONDS = 2.0
GRADLEW_BIN = os.path.join(CHECKOUT_ROOT,
‘examples/androidtests/third_party/gradle/gradlew’)
ADB_BIN = os.path.join(CHECKOUT_ROOT,
‘third_party/android_sdk/public/platform-tools/adb’)
AAR_PROJECT_DIR = os.path.join(CHECKOUT_ROOT, ‘examples/aarproject’)
AAR_PROJECT_GRADLE = os.path.join(AAR_PROJECT_DIR, ‘build.gradle’)
AAR_PROJECT_APP_GRADLE = os.path.join(AAR_PROJECT_DIR, ‘app’, ‘build.gradle’)
AAR_PROJECT_DEPENDENCY = “implementation ‘org.webrtc:google-webrtc:1.0.+'”
AAR_PROJECT_VERSION_DEPENDENCY = “implementation ‘org.webrtc:google-webrtc:%s'”

def _ParseArgs():
parser = argparse.ArgumentParser(description=’Releases WebRTC on Bintray.’)
parser.add_argument(‘–use-goma’,
action=’store_true’,
default=False,
help=’Use goma.’)
parser.add_argument(‘–skip-tests’,
action=’store_true’,
default=False,
help=’Skips running the tests.’)
parser.add_argument(
‘–publish’,
action=’store_true’,
default=False,
help=’Automatically publishes the library if the tests pass.’)
parser.add_argument(
‘–build-dir’,
default=None,
help=’Temporary directory to store the build files. If not specified, ‘
‘a new directory will be created.’)
parser.add_argument(‘–verbose’,
action=’store_true’,
default=False,
help=’Debug logging.’)
return parser.parse_args()

def _GetCommitHash():
commit_hash = subprocess.check_output([‘git’, ‘rev-parse’, ‘HEAD’],
cwd=CHECKOUT_ROOT).strip()
return commit_hash

def _GetCommitPos():
commit_message = subprocess.check_output(
[‘git’, ‘rev-list’, ‘–format=%B’, ‘–max-count=1’, ‘HEAD’],
cwd=CHECKOUT_ROOT)
commit_pos_match = re.search(COMMIT_POSITION_REGEX, commit_message,
re.MULTILINE)
if not commit_pos_match:
raise Exception(‘Commit position not found in the commit message: %s’ %
commit_message)
return commit_pos_match.group(1)

def _UploadFile(user, password, filename, version, target_file):
# URL is of format:
# <repository_api>/<version>/<group_id>/<artifact_id>/<version>/<target_file>
# Example:
# https://api.bintray.com/content/google/webrtc/google-webrtc/1.0.19742/org/webrtc/google-webrtc/1.0.19742/google-webrtc-1.0.19742.aar

target_dir = version + ‘/’ + GROUP_ID + ‘/’ + ARTIFACT_ID + ‘/’ + version
target_path = target_dir + ‘/’ + target_file
url = CONTENT_API + ‘/’ + target_path

logging.info(‘Uploading %s to %s’, filename, url)
with open(filename) as fh:
file_data = fh.read()

for attempt in xrange(UPLOAD_TRIES):
try:
response = requests.put(url,
data=file_data,
auth=(user, password),
timeout=API_TIMEOUT_SECONDS)
break
except requests.exceptions.Timeout as e:
logging.warning(‘Timeout while uploading: %s’, e)
time.sleep(UPLOAD_RETRY_BASE_SLEEP_SECONDS**attempt)
else:
raise Exception(‘Failed to upload %s’ % filename)

if not response.ok:
raise Exception(‘Failed to upload %s. Response: %s’ %
(filename, response))
logging.info(‘Uploaded %s: %s’, filename, response)

def _GeneratePom(target_file, version, commit):
env = jinja2.Environment(loader=jinja2.PackageLoader(‘release_aar’), )
template = env.get_template(‘pom.jinja’)
pom = template.render(version=version, commit=commit)
with open(target_file, ‘w’) as fh:
fh.write(pom)

def _TestAAR(tmp_dir, username, password, version):
“””Runs AppRTCMobile tests using the AAR. Returns true if the tests pass.”””
logging.info(‘Testing library.’)
env = jinja2.Environment(loader=jinja2.PackageLoader(‘release_aar’), )

gradle_backup = os.path.join(tmp_dir, ‘build.gradle.backup’)
app_gradle_backup = os.path.join(tmp_dir, ‘app-build.gradle.backup’)

# Make backup copies of the project files before modifying them.
shutil.copy2(AAR_PROJECT_GRADLE, gradle_backup)
shutil.copy2(AAR_PROJECT_APP_GRADLE, app_gradle_backup)

try:
maven_repository_template = env.get_template(‘maven-repository.jinja’)
maven_repository = maven_repository_template.render(
url=MAVEN_REPOSITORY, username=username, password=password)

# Append Maven repository to build file to download unpublished files.
with open(AAR_PROJECT_GRADLE, ‘a’) as gradle_file:
gradle_file.write(maven_repository)

# Read app build file.
with open(AAR_PROJECT_APP_GRADLE, ‘r’) as gradle_app_file:
gradle_app = gradle_app_file.read()

if AAR_PROJECT_DEPENDENCY not in gradle_app:
raise Exception(‘%s not found in the build file.’ %
AAR_PROJECT_DEPENDENCY)
# Set version to the version to be tested.
target_dependency = AAR_PROJECT_VERSION_DEPENDENCY % version
gradle_app = gradle_app.replace(AAR_PROJECT_DEPENDENCY,
target_dependency)

# Write back.
with open(AAR_PROJECT_APP_GRADLE, ‘w’) as gradle_app_file:
gradle_app_file.write(gradle_app)

# Uninstall any existing version of AppRTCMobile.
logging.info(
‘Uninstalling previous AppRTCMobile versions. It is okay for ‘
‘these commands to fail if AppRTCMobile is not installed.’)
subprocess.call([ADB_BIN, ‘uninstall’, ‘org.appspot.apprtc’])
subprocess.call([ADB_BIN, ‘uninstall’, ‘org.appspot.apprtc.test’])

# Run tests.
try:
# First clean the project.
subprocess.check_call([GRADLEW_BIN, ‘clean’], cwd=AAR_PROJECT_DIR)
# Then run the tests.
subprocess.check_call([GRADLEW_BIN, ‘connectedDebugAndroidTest’],
cwd=AAR_PROJECT_DIR)
except subprocess.CalledProcessError:
logging.exception(‘Test failure.’)
return False # Clean or tests failed

return True # Tests pass
finally:
# Restore backups.
shutil.copy2(gradle_backup, AAR_PROJECT_GRADLE)
shutil.copy2(app_gradle_backup, AAR_PROJECT_APP_GRADLE)

def _PublishAAR(user, password, version, additional_args):
args = {
‘publish_wait_for_secs’: 0 # Publish asynchronously.
}
args.update(additional_args)

url = CONTENT_API + ‘/’ + version + ‘/publish’
response = requests.post(url,
data=json.dumps(args),
auth=(user, password),
timeout=API_TIMEOUT_SECONDS)

if not response.ok:
raise Exception(‘Failed to publish. Response: %s’ % response)

def _DeleteUnpublishedVersion(user, password, version):
url = PACKAGES_API + ‘/versions/’ + version
response = requests.get(url,
auth=(user, password),
timeout=API_TIMEOUT_SECONDS)
if not response.ok:
raise Exception(‘Failed to get version info. Response: %s’ % response)

version_info = json.loads(response.content)
if version_info[‘published’]:
logging.info(‘Version has already been published, not deleting.’)
return

logging.info(‘Deleting unpublished version.’)
response = requests.delete(url,
auth=(user, password),
timeout=API_TIMEOUT_SECONDS)
if not response.ok:
raise Exception(‘Failed to delete version. Response: %s’ % response)

def ReleaseAar(use_goma, skip_tests, publish, build_dir):
version = ‘1.0.’ + _GetCommitPos()
commit = _GetCommitHash()
logging.info(‘Releasing AAR version %s with hash %s’, version, commit)

user = os.environ.get(‘BINTRAY_USER’, None)
api_key = os.environ.get(‘BINTRAY_API_KEY’, None)
#if not user or not api_key:
# raise Exception(
# ‘Environment variables BINTRAY_USER and BINTRAY_API_KEY ‘
# ‘must be defined.’)

# If build directory is not specified, create a temporary directory.
use_tmp_dir = not build_dir
if use_tmp_dir:
build_dir = tempfile.mkdtemp()

try:
base_name = ARTIFACT_ID + ‘-‘ + version
aar_file = os.path.join(build_dir, base_name + ‘.aar’)
third_party_licenses_file = os.path.join(build_dir, ‘LICENSE.md’)
pom_file = os.path.join(build_dir, base_name + ‘.pom’)

logging.info(‘Building at %s’, build_dir)
BuildAar(ARCHS,
aar_file,
use_goma=use_goma,
ext_build_dir=os.path.join(build_dir, ‘aar-build’))
_GeneratePom(pom_file, version, commit)

#_UploadFile(user, api_key, aar_file, version, base_name + ‘.aar’)
#_UploadFile(user, api_key, third_party_licenses_file, version,
# ‘THIRD_PARTY_LICENSES.md’)
#_UploadFile(user, api_key, pom_file, version, base_name + ‘.pom’)

tests_pass = skip_tests or _TestAAR(build_dir, user, api_key, version)
if not tests_pass:
logging.info(‘Discarding library.’)
#_PublishAAR(user, api_key, version, {‘discard’: True})
_DeleteUnpublishedVersion(user, api_key, version)
raise Exception(‘Test failure. Discarded library.’)

if publish:
logging.info(‘Publishing library.’)
#_PublishAAR(user, api_key, version, {})
else:
logging.info(
‘Note: The library has not not been published automatically.’
‘ Please do so manually if desired.’)
finally:
if use_tmp_dir:
shutil.rmtree(build_dir, True)

def main():
args = _ParseArgs()
logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)
ReleaseAar(args.use_goma, args.skip_tests, args.publish, args.build_dir)

if __name__ == ‘__main__’:
sys.exit(main())
再进入src目下,执行:tools_webrtc/android/release_aar.py –verbose –build-dir out/aar_release

–build-dir是只输出目录

输出结果如下:

INFO:root:Releasing AAR version 1.0.33829 with hash 448d18b18d57871d1030fc8748b34250e48be385
INFO:root:Building at out/aar_release
INFO:root:Building: armeabi-v7a
DEBUG:root:Running: [‘/usr/bin/python’, ‘/home/proj/webrtc_linux/src/third_party/depot_tools/gn.py’, ‘gen’, ‘out/aar_release/aar-build/armeabi-v7a’, ‘–args=arm_version=7 use_goma=false target_cpu=”arm” is_component_build=false is_debug=false rtc_include_tests=false target_os=”android”‘]
Done. Made 5367 targets from 299 files in 5600ms
DEBUG:root:Running: [‘/home/proj/webrtc_linux/src/third_party/depot_tools/ninja’, ‘-C’, ‘out/aar_release/aar-build/armeabi-v7a’, ‘sdk/android:libwebrtc’, ‘sdk/android:libjingle_peerconnection_so’]
ninja: Entering directory `out/aar_release/aar-build/armeabi-v7a’
[3774/3774] STAMP obj/sdk/android/libwebrtc.stamp
INFO:root:Building: arm64-v8a
DEBUG:root:Running: [‘/usr/bin/python’, ‘/home/proj/webrtc_linux/src/third_party/depot_tools/gn.py’, ‘gen’, ‘out/aar_release/aar-build/arm64-v8a’, ‘–args=use_goma=false target_cpu=”arm64″ is_component_build=false is_debug=false rtc_include_tests=false target_os=”android”‘]
Done. Made 5364 targets from 299 files in 1442ms
DEBUG:root:Running: [‘/home/proj/webrtc_linux/src/third_party/depot_tools/ninja’, ‘-C’, ‘out/aar_release/aar-build/arm64-v8a’, ‘sdk/android:libwebrtc’, ‘sdk/android:libjingle_peerconnection_so’]
ninja: Entering directory `out/aar_release/aar-build/arm64-v8a’
[3709/3709] STAMP obj/sdk/android/libwebrtc.stamp
INFO:root:Building: x86
DEBUG:root:Running: [‘/usr/bin/python’, ‘/home/proj/webrtc_linux/src/third_party/depot_tools/gn.py’, ‘gen’, ‘out/aar_release/aar-build/x86’, ‘–args=use_goma=false target_cpu=”x86″ is_component_build=false is_debug=false rtc_include_tests=false target_os=”android”‘]
Done. Made 5383 targets from 301 files in 1083ms
DEBUG:root:Running: [‘/home/proj/webrtc_linux/src/third_party/depot_tools/ninja’, ‘-C’, ‘out/aar_release/aar-build/x86’, ‘sdk/android:libwebrtc’, ‘sdk/android:libjingle_peerconnection_so’]
ninja: Entering directory `out/aar_release/aar-build/x86′
[3896/3896] STAMP obj/sdk/android/libwebrtc.stamp
INFO:root:Building: x86_64
DEBUG:root:Running: [‘/usr/bin/python’, ‘/home/proj/webrtc_linux/src/third_party/depot_tools/gn.py’, ‘gen’, ‘out/aar_release/aar-build/x86_64’, ‘–args=use_goma=false target_cpu=”x64″ is_component_build=false is_debug=false rtc_include_tests=false target_os=”android”‘]
Done. Made 5383 targets from 301 files in 1024ms
DEBUG:root:Running: [‘/home/proj/webrtc_linux/src/third_party/depot_tools/ninja’, ‘-C’, ‘out/aar_release/aar-build/x86_64’, ‘sdk/android:libwebrtc’, ‘sdk/android:libjingle_peerconnection_so’]
ninja: Entering directory `out/aar_release/aar-build/x86_64′
[3892/3892] STAMP obj/sdk/android/libwebrtc.stamp
INFO:root:Collecting common files.
INFO:root:Collecting: armeabi-v7a
INFO:root:Collecting: arm64-v8a
INFO:root:Collecting: x86
INFO:root:Collecting: x86_64
到*后生成的文件如下:

%title插图%num

python – 内置对象 之 自定义函数

python – 内置对象 之 自定义函数

目录

一、自定义函数基础

1.定义一个函数

2.函数调用

3.参数传递

4.函数参数类型

二、函数变量作用域

1.理解变量作用域

2.全局变量与局部变量

三、lambda匿名函数

1.lambda函数定义

2.lambda函数实例

3.lambda函数的特点和使用场景

四、return返回特性

1.return返回元组列表字典

2.return跳出循环或终止执行下面语句

 

一、自定义函数基础
1.定义一个函数
# 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
# 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
# 函数的*行语句可以选择性地使用文档字符串—用于存放函数说明。
# 函数内容以冒号起始,并且缩进。
# return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
2.函数调用
函数名([形参值])
# 形参值指创建函数时要求传入的各个形参的值。注意,创建函数时有多少个形参,那么调用时就需要传入多少个值,且顺序必须和创建函数时一致。即便该函数没有参数,函数名后的小括号也不能省略。
在定义函数时,函数名后面括号中的变量名称叫做形式参数,或者称为形参。
在调用函数时,函数名后面括号中的变量名称叫做实际参数,或者称为实参。
3.参数传递
(1)不可变类型

# 如整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
#!/usr/bin/python

# -*- coding: UTF-8 -*-

def ChangeInt( a ):

a = 10

b = 2

ChangeInt(b)

print(b) # 结果是 2
(2)传可变对象实例

# 如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
(2)传可变对象实例
# 如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 可写函数说明
def changeme( mylist ):
“修改传入的列表”
mylist.append([1,2,3,4]);
print(“函数内取值: “, mylist)
return

# 调用changeme函数
mylist = [10,20,30];
changeme( mylist );
print(“函数外取值: “, mylist)
# 函数内取值: [10, 20, 30, [1, 2, 3, 4]]
# 函数外取值: [10, 20, 30, [1, 2, 3, 4]]
4.函数参数类型
# 必备参数 # 关键字参数 # 默认参数 # 不定长参数

(1)必备参数

# 必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。

def printme( str1,str2 ):
“打印任何传入的字符串”
print(str1,str2);
return;

#调用printme函数
printme(‘john’,’harry’);
(2)关键字参数

# 函数调用使用关键字参数来确定传入的参数值,使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

def printinfo( name, age ):
“打印任何传入的字符串”
print “Name: “, name;
print “Age “, age;
return;

#调用printinfo函数
printinfo( age=50, name=”miki” );
(3)默认参数

# 调用函数时,默认参数的值如果没有传入,则被认为是默认值。下例会打印默认的age,如果age没有被传入:

def printinfo( name, age = 35 ):
“打印任何传入的字符串”
print “Name: “, name;
print “Age “, age;
return;

#调用printinfo函数
printinfo( age=50, name=”miki” );
printinfo( name=”miki” );
(4)不定长参数:*args 和 **kwargs

元组参数,即 *args,参数格式化存储在一个元组中,长度没有限制,必须位于普通参数和默认参数之后。在函数调用时,*会以单个元素的形式解包一个元祖,使其成为独立的参数。
字典参数,即 **kwargs,参数格式化存储在一个字典中,必须位于参数列表的*后面。**会以键/值对的形式解包一个字典,使其成为独立的关键字参数。
#*args例子
def printinfo( arg1, *vartuple ):
“打印任何传入的参数”
print “输出: ”
print arg1
for var in vartuple:
print var
return;

# 调用printinfo 函数
printinfo( 10 );
printinfo( 70, 60, 50 );
# 输出:
# 10
# 输出:
# 70
# 60
# 50

#**kwargs例子
def print_values(**kwargs):
for key, value in kwargs.items():
print(“The value of {} is {}”.format(key, value))

print_values(my_name=”Sammy”, your_name=”Casey”)

def fun(name, age=1, *args, **kwargs):
print(‘Hello’, name, age, ‘年’) # Hello World 1 年
print(args) # (‘I’, ‘love’, ‘it’)
for i in args:
print(i)
print(kwargs) # {‘my’: ‘jack’, ‘like’: ‘girl’}
for m in kwargs:
print(m, ‘:’, kwargs[m])

fun(‘World’, 1, ‘I’, ‘love’, ‘it’, my=’jack’, like=’girl’)
# 结果:
# Hello World 1 年
# (‘I’, ‘love’, ‘it’)
# I
# love
# it
# {‘my’: ‘jack’, ‘like’: ‘girl’}
# my : jack
# like : girl
(5)关于**kwargs、位置参数、*args、默认参数混用问题:(注意顺序)

# 位置参数、*args、**kwargs三者的顺序必须是:位置参数、*args、**kwargs,否则会出错。
def func(x,*args,**kwargs):
print(‘x = ‘,x)
print(‘args = ‘,args)
print(‘kwargs = ‘,kwargs)

func(1,2,3,4,y=1,a=2,b=3,c=4)
# 结果:
# x = 1
# args = (2, 3, 4)
# kwargs = {‘b’: 3, ‘c’: 4, ‘a’: 2, ‘y’: 1}
位置参数、默认参数、**kwargs的顺序必须为:位置参数、默认参数、**kwargs,否则会报错。

def func(x,y=2,**kwargs):
print(‘x = ‘,x)
print(‘y = ‘,y)
print(‘kwargs = ‘,kwargs)

func(1,y=1,a=2,b=3,c=4)
# 结果为:
x = 1
y = 1
kwargs = {‘c’: 4, ‘a’: 2, ‘b’: 3}
二、函数变量作用域
1.理解变量作用域
(1)变量的作用域

在Python程序中创建、改变、查找变量名时,都是在一个保存变量名的空间中进行,我们称之为命名空间,也被称之为作用域。python的作用域是静态的,在源代码中变量名被赋值的位置决定了该变量能被访问的范围。即Python变量的作用域由变量所在源代码中的位置决定。
(2)作用域的产生

就作用域而言,Python与C有着很大的区别,在Python中并不是所有的语句块中都会产生作用域。只有当变量在Module(模块)、Class(类)、def(函数)中定义的时候,才会有作用域的概念。
需要注意的是:在if-elif-else、for-else、while、try-except\try-finally等关键字的语句块中并不会产成作用域。
(3)作用域的类型

# L (Local) 局部作用域
# E (Enclosing) 闭包函数外的函数中
# G (Global) 全局作用域
# B (Built-in) 内建作用域
(4)查找规则

# 以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找。
# 闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
x = int(2.9) # 内建作用域B
g_count = 0 # 全局作用域G
def outer():
o_count = 1 # 闭包函数外的函数中E
def inner():
i_count = 2 # 局部作用域L
2.全局变量与局部变量
# 局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。
# 当内部作用域想修改外部作用域的变量时,就要用到 global 和 nonlocal 关键字了。
(1)修改全局变量

num = 1
def fun1():
global num # 需要使用 global 关键字声明
print(num)
num = 123
print(num)
fun1()
print(num)

# >>>
# 1
# 123
# 123
(2)修改嵌套作用域中的变量

def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print(num)
inner()
print(num)
outer()

# >>>
# 100
# 100
三、lambda匿名函数
1.lambda函数定义
# python 使用 lambda 来创建匿名函数。lambda函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,…..argn]]:expression
# lambda 函数可以接收任意多个参数 (包括可选参数) 并且返回单个表达式的值。
# lambda匿名函数的格式:冒号前是参数,可以有多个,用逗号隔开,冒号右边的为表达式。其实lambda返回值是一个函数的地址,也就是函数对象。
2.lambda函数实例
s=lambda x,y:x+y

h=lambda x,y,z:x+y-z

print(s(10,20),h(10,20,50))

 

3.lambda函数的特点和使用场景
(1)特点

# 从函数命名的角度:匿名,直接返回可供调用的值
# 从输入输出的角度:支持多个输入参数,但只支持一个表达式
# 从函数功能的角度:结构简单,无须定义函数名。但所能实现的功能也*其受限。
# 从访问变量的角度:只支持访问lambda自己定义的变量。不支持外部变量访问
# 从运行效率的角度:lambda实际上仍开辟了一个内存单元,并没有提升运行效率
(2)使用场景

# lambda函数复制给变量:减少函数定义的麻烦,同时支持代码复用。
# lambda函数赋值给函数:利用lambda函数实现对已有函数的重新定义。
# 利用lambda函数进行函数嵌套:利用lambda构造嵌套的内部和外部函数,实现闭包编程
# 将lambda函数作为参数传递给其他函数
部分Python内置函数接收函数作为参数。典型的此类内置函数有这些。

filter函数

此时lambda函数用于指定过滤列表元素的条件。

filter(lambda x: x % 3 == 0, [1, 2, 3])

指定将列表[1,2,3]中能够被3整除的元素过滤出来,其结果是[3]。

sorted函数

此时lambda函数用于指定对列表中所有元素进行排序的准则。

sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x))

将[1, 2, 3, 4, 5, 6, 7, 8, 9]按照与5距离从小到大进行排序,结果是[5, 4, 6, 3, 7, 2, 8, 1, 9]

map函数

此时lambda函数用于指定对列表中每一个元素的共同操作。

如map(lambda x: x+1, [1, 2,3])

将列表[1, 2, 3]中的元素分别加1,其结果[2, 3, 4]。

reduce函数

此时lambda函数用于指定列表中两两相邻元素的结合条件。

reduce(lambda a, b: ‘{}, {}’.format(a, b), [1, 2, 3, 4, 5, 6, 7, 8, 9])

将[1, 2, 3, 4, 5, 6, 7, 8, 9]中元素从左往右两两以逗号分隔的字符的形式依次结合起来,其结果是’1, 2, 3, 4, 5, 6, 7, 8, 9’。

 

四、return返回特性
1.return返回元组列表字典
(1)返回元组

def func():
x=0
y=1
z=2
return x,y #返回元组

print(type(func()))
(2)返回列表

def func():
x=0
y=1
z=2
return [x,y] #返回列表

print(type(func()))
(3)返回字典

def func():
x=0
y=1
z=2
return {x,y} #返回字典

print(type(func()))
2.return跳出循环或终止执行下面语句
执行到return语句时,会退出函数,return之后的语句不再执行,有循环也会跳出循环。但将return语句放在try语句块中,是个例外。
(1)普通情况:遇return退出函数,不执行return之后语句

def test_return(x):
if x > 0:
return x
else:
return 0
(2)有循环也出跳出循环

def test_return(x):
for i in range(x):
if i>=4:
return i
print(i)

test_return(10)
#结果:
#0
#1
#2
#3

def return_y(j):
while j<10:
print(j)
j+=1
if j==3:
return 3
print(return_y(1))
#结果:
1
2
3
(3)try..finally 结构中的return,遇到return后,还是会执行finally中的语句

def func():
try:
print(98)
return ‘ok’ # 函数得到了一个返回值
finally: # finally语句块中的语句依然会执行
print(18)

print(func())
#结果:
#98
#18
#ok
(4)try..finally 结构中各有一个return,*后返回的是finally中的return

def func():
try:
x=0
y=1
z=2
return [x,y] # 函数得到了一个返回值
finally: #finally语句块中的语句依然会执行
print(“last return”)
return {x,z}

print(func())
#结果:
#last return
#{0, 2}

当我们谈深度学习时,我们用它落地了什么?阿里云内容安全功能全新升级

现今伴随人工智能在技术上的不断突破,一些领域如计算机视觉,已开始与各个行业进行了深度融合。例如保险行业已通过人脸识别这种新时代的认证方式,来对用户身份信息进行识别与审核。深度学习对人工智能的发展起着至关重要的影响。

近日,阿里云在深度学习方面动作频频,先后发布了OCR证件识别,声纹检测,人脸搜索,视频鉴黄服务以及相似图片搜索功能,下面小编就一一为大家介绍五大功能应用。

云盾内容安全敏感人脸搜索商业化发布;主要针对教育,学校,以及部分工厂企业,公安对于违法犯罪份子,以及敏感人物,进行1:N识别服务,客户可以增删减建立和管理自己的人脸库,然后对进入监控环境的人进行敏感人物和危险人物的核对使用。

云盾内容安全相似图片搜索商业化发布;主要为图片版权保护的客户提供侵权判定检测服务,用户可以对自己所拥有版权的图片建立图片库,通过客户自有舆情和关注渠道的图片进行比对判定是否侵权。减少外部盗版对正常业务的资损问题。主要面向摄影类平台使用。

云盾内容安全国际视频鉴黄服务;为国内直播短视频出海用户提供海外视频违法检测能力,因为中国公民也受国内法律监管,而色情在海外也有管控要求 为国际用户提供海外视频鉴黄服务,协助客户解决在所在地的内容合规问题

云盾内容安全-OCR证件识别(公测)发布;OCR证件识别是云盾内容安全通过OCR图文结构化识别的技术方式来辨别证件真伪的一个服务,主要是为需要证件核验单位使用,如税务局,民政局等。主要是帮助客户通过机器的方式来判定而不是人肉,提升识别率,降低人力成本

云盾内容安全-声纹1:1(公测)发布;去年,人民的名义大火,落马官员丁义珍伪造证件潜逃出国。通过云盾声纹的对比,对直播,视频内违法人员及敏感人物落马官员等信息进行识别,无处可逃。

python:String-模版替换操作

python:String-模版替换操作

capwords函数

将序列中的每个单词变成首字母大写

def capwords(s, sep=None):
“””capwords(s [,sep]) -> string
Split the argument into words using split, capitalize each
word using capitalize, and join the capitalized words using
join. If the optional second argument sep is absent or None,
runs of whitespace characters are replaced by a single space
and leading and trailing whitespace are removed, otherwise
sep is used to split and join the words.
“””
return (sep or ‘ ‘).join(x.capitalize() for x in s.split(sep))
从源码中我们在return处可以看到是先使用了split进行切割(默认走空格切割),然后在使用join进行结果的合并

栗子:

import string

s = ‘this is old old man’
print(s)

print(string.capwords(s))
运行后的结果如下

this is old old man
This Is Old Old Man

Process finished with exit code 0
从运行结果看,可以清晰的看出原本小写的单词,*后变成首字母大写了…

 

模版

模版拼接也是内置拼接的代替方法,使用string.Template拼接时,要在名字前加前缀$来标识变量(例如:$var),如果要和周围的变量区分的话,那就加一个花括号(例如:${var})。

栗子:

import string

values = {‘var’: 66}

t = string.Template(“””
variable : $var
escape : $var
variable in text : ${var}和我拼接
“””)
print(t.substitute(values))
print(t.safe_substitute(values))
运行后的结果如下

variable : 66
escape : 66
variable in text : 66和我拼接

variable : 66
escape : 66
variable in text : 66和我拼接
从上述结果来看,数据是已经替换成功了,唯一不好的就是数据都是字符型,如果参数的类型需要更换,就得再做一层处理… 具体怎么做可自行动手操作

 

substitute和safe_substitute方法

substitute处理替换时,存在就替换,不存在则抛KeyError错误

safe_substitute处理替换时,存在就替换,不存在就是原参数返回,不会抛错误

栗子:substitute方法

import string

values = {‘var’: 66}

t = string.Template(“””
variable : $var
escape : $var
missing : $missing
variable in text : ${var}和我拼接
“””)
print(t.substitute(values))
运行后的结果如下

Traceback (most recent call last):
File “/Users/lifeng/python-projects/Test/pythonScripts/python_string.py”, line 21, in <module>
print(t.substitute(values))
File “/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/string.py”, line 121, in substitute
return self.pattern.sub(convert, self.template)
File “/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/string.py”, line 114, in convert
return str(mapping[named])
KeyError: ‘missing’
从上述运行结果可以看出,报错是KeyError:’missing’

 

栗子:safe_substitute方法

import string

values = {‘var’: 66}

t = string.Template(“””
variable : $var
escape : $var
missing : $missing
variable in text : ${var}和我拼接
“””)
print(t.safe_substitute(values))
运行后的结果如下

variable : 66
escape : 66
missing : $missing
variable in text : 66和我拼接

Process finished with exit code 0
从上述运行结果看,没有参数替换的参数,就原参数返回,且不会报错

 

 

可能有些时候我们觉得$符号不舒服,想更换一种符号用,那这样我们就可以继承Template进行重写操作

class MyTemplate(string.Template):
delimiter = ‘!’

l = MyTemplate(“””
variable : !var
escape : !var
missing : $missing
variable in text : ${var}和我拼接
“””)
print(l.substitute(values))
在上述代码中我们只是把源码中的delimiter变量的值修改了,运行后的结果如下

上述代码中我们把定界符$符号修改成了!符号,参数替换也是成功的,当然你如果想重写别处代码也是可以的,因为Template这个类本身就有正则表达式,只要源码看得懂那就改起来吧…

 

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速