python终端打开python文件窗口我的不能打小括号?

使用Python写个小监控
转载 & & 作者:唐千
最近使用python写了个小监控,为什么使用python?简单、方便、好管理,Python如何实现简单的小监控,感兴趣的小伙伴们可以参考一下
首先你得用过C/C++、java、Javascript等的一种,编程小白估计比较艰难,有一定编程经验的python小白相对简单些。
1.1 Hello World!
Python安装比较简单,到官网上下载安装包,一路下一步就可以了。因为我的服务器上安装的是2.6.6,所以我也下了这个版本。话说2.x的差别不是很大,如果想用3.x,可能下面的代码直接运行不过,不过也差不多,稍微改改即可。
新建一个文件,命名为hello.py。使用python的IDLE打开hello.py,写入以下代码:
print "Hello World!"
按F5,就可以看见输出结果了。
1.2 基本语法
每一行是一条语句。C语言是通过分号”;“;
通过缩进来组织代码块。C语言是通过大括号”{}“;
注释使用井号”#“。
1.3 数据类型、运算符、数据结构
运算符和C语言差不多,C语言有的基本上直接用就可以。
数据类型有数值型,字符串。数据结构有 list, tuple, dict, set。介绍一下tuple, 不能修改,通过索引进行查找。dict类似于map,存放键值对。来看例子,看看tuple使用:
&&& t=(1,2,[1,2])
1.4 流程控制
Python中可以使用if elif else、for和 while 来实现流程控制。同样有 break 和 continue。有一点和C不同,如果有一个分支什么都不做,要使用 pass。例如
list=[0, 1, 2, 3, 4, 5]
for item in list:
if item == 1:
print item
elif item in (2, 3, 4, 5):
print "aha " + str(item)
运行结果是:
<span style="color: #
1.5 模块组织
有方法和类。
方法这样定义
def func(var):
some code here
类和C++等有些不同
class MyClass(object):
common = 1
def __init__(self):
self.myvariable = 5
def myfunction(self, arg1, arg2):
return self.myvariable
common变量相当于C++中用 static 修饰的变量,所有类通用;继承也非常简单,可以看看开始推荐的那篇文章。
1.6 异常处理
异常处理非常简单,直接贴代码了:
def some_function():
# Division by zero raises an exception
except ZeroDivisionError:
print "Oops, invalid."
# Exception didn't occur, we're good.
# This is executed after the code block is run
# and all exceptions have been handled, even
# if a new exception is raised while handling.
print "We're done with that."
1.7 工程组织
直接引用库,或者从库中引入某一个方法或变量。
import random
from time import clock
2. 数据库查询
既然是监控,免不了和数据库打交道。我使用的是PostgreSQL,所以就介绍一下python怎么调用postgres。
连接postgres首先要安装一个库psycopg2,Windows下直接下载安装即可,注意选对版本。我的服务器是CentOS,安装直接运行
yum install python-psycopg2
2.1 首先创建数据库连接
#get database connect
def get_con():
host = '127.0.0.1'
port = "5432"
database = 'platform'
user = 'postgres'
password = 'postgres'
conn = psycopg2.connect(database=database, user=user, password=password, host=host, port=port)
return conn
2.2 执行SQL语句
#执行sql查询
def query(conn, sql):
cursor = conn.cursor()
cursor.execute(sql)
results = cursor.fetchall()
#close cursor
cursor.close()
return results
2.3 然后就可以写具体业务了
def getUsers():
conn = get_con()#open connect
sql = """select *
from t_user
order by intime DESC
limit 5"""
items = query(conn , sql)
print str(items)
conn.close() #close connect
注意3个引号”””,就是普通字符串,不过可以换行。
3. 发送邮件
查询到数据之后不能及时通知管理员的话监控就没有意义了。所以我们通过邮件来通知,直接使用python的标准库 smtplib 就可以了。写个发送邮件的函数:
def send_email(subject, content):
sender = "yourmail@***.com"
password = "******" #密码是看不见的哦
receivers = [tq.com] #本人真实邮箱,欢迎发邮件讨论技术问题
host = "smtp.exmail.qq.com"
port = 465
msg = MIMEText(content,'html','utf-8')
msg['From'] = sender
msg['To'] = ",".join(receivers)
msg['Subject'] = Header(subject, 'utf-8')
smtp = smtplib.SMTP_SSL(host, port)
smtp.login(sender, password)
smtp.sendmail(sender, receivers, msg.as_string())
except Exception, e:
logger.error(e)
logger.info(content)
发送邮件时我们使用了logger,这个logger是怎么来的呢?新建一个log.py,代码如下
# coding=utf-8
import logging
import logging.handlers
logger = logging.getLogger('monitor')
logger.setLevel(logging.DEBUG)
filehandler = logging.handlers.TimedRotatingFileHandler(
"/mnt/log/monitor/monitor_log", 'midnight', 1, 7)
# 设置文件后缀名称
filehandler.suffix = "%Y%m%d.log"
formatter = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s: %(message)s')
filehandler.setFormatter(formatter)
logger.addHandler(filehandler)
通过logging.getLogger(‘monitor')生成一个logger,然后配置一个文件处理器。
然后在我们监控程序中引用即可:
from log import logger
5. 把可配置信息放到配置文件中
如果我们添加一个管理员怎么办?如果我们的邮箱密码变了怎么办?直接修改python文件啊,哈哈。python不用编译直接改代码就好了,可是我们的程序以后要打包呢,所以最好写个配置文件,python的配置文件读取非常简单,使用python库 ConfigParser 即可:
config = None
#get config
def getConfig():
global config
if config is None:
config = ConfigParser.ConfigParser()
config.read("monitor.ini")
return config
然后这样使用:
#get database connect
def get_con():
host = getConfig().get('db', 'host')
port = getConfig().get('db', 'port')
database = getConfig().get('db', 'database')
user = getConfig().get('db', 'user')
password = getConfig().get('db', 'password')
conn = psycopg2.connect(database=database, user=user, password=password, host=host, port=port)
return conn
def send_email(subject, content):
sender = getConfig().get('mail', 'sender')
password = getConfig().get('mail', 'password')
receivers = getConfig().get('mail', 'receivers').split(",")
host = getConfig().get('mail', 'host')
port = getConfig().getint('mail', 'port')
msg = MIMEText(content,'html','utf-8')
msg['From'] = sender
msg['To'] = ",".join(receivers)
msg['Subject'] = Header(subject, 'utf-8')
smtp = smtplib.SMTP_SSL(host, port)
smtp.login(sender, password)
smtp.sendmail(sender, receivers, msg.as_string())
logger.exception("Exception: ")
logger.info(content)
配置文件是monitor.ini,内容如下:
#数据库配置
host = 127.0.0.1
port = 5432
database = platform
user = postgres
password = postgres
password = ******
#多个联系人用英文逗号隔开
receivers = tq.com
host = smtp.exmail.qq.com
port = 465
6. 加点控制
我们每5分钟查一下数据,可是业务sql只能查询最近的几条,所以要加个时间段限制,弄个开始、结束时间。
start_time = " 16:24:24"
end_time = None
#update end_time, invoke before get new data
def update_end_time():
global end_time
now = time.mktime(datetime.now().timetuple())
end_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(now))
return end_time
#update end_time, invoke after get new data
def update_start_time():
global start_time
global end_time
start_time = end_time
return start_time
getUsers可以改写成:
def getUsers (conn):
global start_time
global end_time
sql = """select *
from t_user
where intime&=""" +"'"+start_time+"' and intime&"+"'"+end_time+"';"
items = query(conn, sql)
if items is not None and len(items)&0:
count = len(items)
tip = "又有"+str(count)+"个用户已经注册了。"+end_time
send_email(tip, tip+"\n"+str(items))
然后写个统一的调度:
def task():
#init end_time and start_time, must init end_time first!!!
end_time = update_end_time()
start_time = update_start_time()
#init config
getConfig()
while True:
conn = get_con()
#open connect
end_time = update_end_time()
############## process ##############
logger.info("query: "+end_time)
getUsers (conn)
#do some task else here
update_start_time()
conn.close()#close connect
time.sleep(5*60)
#end of while
def run_monitor():
monitor = threading.Thread(target=task)
monitor.start()
if __name__ == "__main__":
run_monitor()
在task这个函数的while中,首先更新end_time,也就是当前时间;执行完再把start_time更新成刚刚的end_time,这样就不会有漏网之鱼了。还有一个需要注意的地方,关键字global。 在python中,使用全局变量是需要global关键字进行声明的,否则会出问题。
打开linux 控制台,直接运行python monitor.py是可以运行的,可是shell一旦退出,任务也就停止了。于是我就选择了一个进程管理工具:Supervisor。Supervisor 在进程中断时还能自动重启。
7.1. 安装supervisor
首先安装python-setuptools
yum install python-setuptools
安装supervisor
easy_install supervisor
生成supervisor配置文件
echo_supervisord_conf & /etc/supervisord.conf
然后在/etc/supervisord.conf添加:
[program:monitor]
command = python /usr/monitor/monitor.py
directory = /usr/monitor
user = root
7.2. 运行监控
然后在终端中运行supervisord启动supervisor。
在终端中运行supervisorctl,进入shell,运行status查看脚本的运行状态。
7.3. 关闭监控 以及常用命令
以下命令全部在supervisorctl的shell中执行。
shutdown 停止Supervisor(子进程也会被停止) ;
start monitor 开启monitor进程服务(一旦monitor进程退出,会自启动) ;
stop monitor 关闭monitor进程服务 ;
restart monitor 关闭正在运行的monitor进程,并且重新启动monitor进程服务 ;
reload 重新加载supervisor配置文件 ;
exit 退出supervisorctl的shell。
程序基本上就写完了,也可以跑起来了,是不是很酷,大家快点动手实践一下吧!
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具52被浏览9,186分享邀请回答&&& import re
&&& help(re.findall)
Help on function findall in module re:
findall(pattern, string, flags=0)
Return a list of all non-overlapping matches in the string.
If one or more capturing groups are present in the pattern, return
a list of groups; this will be a list of tuples if the pattern
has more than one group.
Empty matches are included in the result.
意思很明显,分组匹配下(一对括号内是一个组),findall函数返回元组形式的匹配结果,并且匹配为空也会返回到元组中。所以一般用法是这样的:&&& a = "one two three four five six"
&&& import re
&&& b = re.findall(r"(one) (two) (three) (four) (five) (six)",a)#去掉了"|"号
&&& print(b)
[('one', 'two', 'three', 'four', 'five', 'six')]#按组将匹配结果添加到元组中返回
&&& b = re.findall(r"(one) (two) (three) (four)",a)
#不完全匹配
&&& print(b)
[('one', 'two', 'three', 'four')]
#按组返回匹配成功部分,列表长度为1
&&& b = re.findall(r"one|two|three|four|five|six",a)
#不安组的条件匹配
&&& print(b)
['one', 'two', 'three', 'four', 'five', 'six']#返回长度为6的列表
&&& b = re.findall(r"one two three four five six",a)
&&& print(b)
['one two three four five six'] #完全匹配,返回长度为1的列表
&&& b = re.findall(r"(one) (two) (three) (four) (five) (six) (seven)",a)
&&& print(b)
[]# 没法全部匹配,返回空
&&& print (re.findall(r"[abc]","abc"))#[]的效果
['a','b','c']
&&& print (re.findall(r"a|b|c","abc"))#"|"的效果
['a','b','c']
通过以上实验可以得出的结论:1条件匹配符"|"使得findall按每一种条件匹配一次,且"|"和"[]"效果是相同的,返回形式一样。2圆括号分组匹配使得findall返回元组,元组中,几对圆括号就有几个元素,保留空匹配。再看我提问中举的例子,将条件匹配与分组匹配结合在了一起。&&& a = "one two three four five six"
&&& b = re.findall("(one)|(two)|(three)|(four)|(five)|(six)",a)#加上了"|"号
&&& print(b)
[('one', '', '', '', '', ''), ('', 'two', '', '', '', ''),
('', '', 'three', '', '', ''),('', '', '', 'four', '', ''),
('', '', '', '', 'five', ''),('', '', '', '', '', 'six')]
于是就理解了:1这个结果是因为按组匹配所以有元组,每个元组都有六个元素。2而因为是条件匹配,列了六种匹配条件,于是findall匹配六次,结果列表有六个元素。3又因为每次匹配只能用一种条件,所以按组匹配结果列表中的每个元组只有一组有值而其他均为空。这有什么用呢?比如:&&& x = "3 min 46 sec 300 ms"
#分秒毫秒的提取
&&& print(re.findall(r"(\d{0,}) (min|sec|ms)",x))
[('3', 'min'), ('46', 'sec'), ('300', 'ms')] #会不会很方便?
--------------------------------------------------------------------------------------------------这个理解其实对下面那个问题(如何匹配某种单词搭配)没什么用,因为还有一个符号没有介绍,那就是"?:"符号,表示取消按分组返回。#这个正则式子是随意写就的,
#按照人的思维理解。
#这个式子匹配以h或s为开头,ef或cd的(a或b)结尾为结尾的东西。
#一共有2*2*2八种可能性,findall的结果会有八个元素。
&&& print(re.findall(r"\b((h|s)(ef|(cd|(a|b))))\b","sef scd sa sb hef hcd ha hb"))
#不添加?:符号时结果如下:
#正则式子中的括号一共有五个,所以返回列表里的每个元组有五个元素
[('sef', 's', 'ef', '', ''), ('scd', 's', 'cd', 'cd', ''),
('sa', 's', 'a', 'a', 'a'), ('sb', 's', 'b', 'b', 'b'),
('hef', 'h', 'ef', '', ''), ('hcd', 'h', 'cd', 'cd', ''),
('ha', 'h', 'a', 'a', 'a'), ('hb', 'h', 'b', 'b', 'b')]
#下面是加上"?:"的结果
&&&print(re.findall(r"\b(?:(?:h|s)(?:ef|(?:cd|(?:a|b))))\b","sef scd sa sb hef hcd ha hb"))
['sef', 'scd', 'sa', 'sb', 'hef', 'hcd', 'ha', 'hb']
第一个式子返回的结果其实也算OK,因为已经覆盖到了所有的可能,只不过冗余项比较多,想得到纯粹的结果还要处理一次。第二个式子加了"?:"后就简洁许多。作为初学者,可能用不到分组这么复杂的正则式子,也就更不用提取消分组的符号了,所以很多正则的入门教程并不会花太多时间在这两项上。所以现在就介绍一下如何解决匹配单词搭配的问题。就比如说找数量结构的词组吧。我们先进行书面的结构分析数量结构是一种表示数量关系的短语,比如汉语中的一斤酒一两牛肉,由数词+量词+名词构成,也可以是一下,轻轻一按,用力一踢,由副词/+数词+动词构成。在英语中数量结构又分为两种。第一种是 a/an + n1 + of + n2,其中n1、n2是名词。比如 a piece of bread 。这种结构往往用来修饰不可数名词。第二种是 num. + n 这个简单,就是数词+可数名词的复数形式,穷举所有的数词就行了。第一种的正则式很简单,是这样的:r"\ban{0,1}\b \b\w+\b \bof\b \b\w+\b" #凡是在不定冠词和of之间的必然是名词,在of之外的是名词
第二种就稍微复杂一点,我们要把所有的数词都列出来,寻找其中的规律差不多能分出这么几组没有规律的:(?:hundred|thounsand|million|billion|trillion|one|two|three|ten|five|eleven|twelve twenty|forty)结尾可加teen也可不加的:(?:(?:four)(?:teen){0,1})结尾可加teen或ty也可不加的 :(?:(?:six|seven|eight|nine)|(?:ty|teen))结尾必须加teen或ty的: (?:(?:fif|thir)(?:ty|teen))把他们组合起来就是:r"(?:(?:hundred|thounsand|million|billion|trillion|one|two|three|ten|five|eleven|twelve |twenty|forty)|(?:(?:four)(?:teen){0,1})|(?:(?:six|seven|eight|nine)|(?:ty|teen))|(?:(?:fif|thir)(?:ty|teen)))\b"
再加上第一种可能就成了:(?:\ban{0,1}\b \b\w+\b \bof\b)|(?:(?:(?:hundred|thounsand|million|billion|trillion|one|two|three|ten|five|eleven|twelve|twenty|forty)|(?:(?:four)(?:teen){0,1})|(?:(?:six|seven|eight|nine)|(?:ty|teen))|(?:(?:fif|thir)(?:ty|teen)))\b)
这还只是选了前部分,后面还要接一个名词,所以:(?:(?:\ban{0,1}\b \b\w+\b \bof\b)|(?:(?:(?:hundred|thounsand|million|billion|trillion|one|two|three|ten|five|eleven|twelve|twenty|forty)|(?:(?:four)(?:teen){0,1})|(?:(?:six|seven|eight|nine)|(?:ty|teen))|(?:(?:fif|thir)(?:ty|teen)))\b)) (?:\b\w+\b)
于是这就是是完成状态了,我们来检测一下成果吧:input
import rea = "a cup of tea million stars forty people "
b = re.compile(r"(?:(?:\ban{0,1}\b \b\w+\b \bof\b)|(?:(?:(?:hundred|thounsand|million|billion|trillion|one|two|three|ten|five|eleven|twelve|twenty|forty)|(?:(?:four)(?:teen){0,1})|(?:(?:six|seven|eight|nine)|(?:ty|teen))|(?:(?:fif|thir)(?:ty|teen)))\b)) (?:\b\w+\b)")
print(re.findall(b,a))
['a cup of tea', 'million stars', 'forty people']
这种眼花缭乱的式子,看着很麻烦,也不好解读,还好python提供了松散正则表达式。只要在re.comile的第二个参数上填上"re.VERBOSE"即可写成如'''example'''注释的形式,此时空格不再被匹配,必须使用\s表达(下面这个版本已经更新了,这次更新囊括了所有的序数词):a = "give me a kiss million stars one piece"
b = re.compile(r"""
#随时可以以#号备注
(?:\b\w+\b\s\b\w+\b\s)?
(?:\ban?\b\s\b\w+\b\s\bof\b)
|#第一类数量结构
(?:\b(?:one|two|three|five|first|second|third|fifth|sixth|an?))
|#fifth在这里 没有规律的数词 fifth sixth
(?:(?:hundred|thounsand|million|billion|trillion|ten|eleven|twel(?:f|ve))(?:th)?)
(?:(?:twent|fort)(?:y|ieth))
(?:(?:four)(?:teen|th)?)
|#加不加teen皆可的数词
(?:(?:six|seven|eight?|nine?)(?:(?:(?:t[yh])(?:eth)?)|(?:teen)(?:th)?)?)
|#加不加teen或ty皆可的数词
(?:(?:fif|thir)(?:(?:t[yi])(?:eth)?|(?:teen)(?:th)?))
#必须加teen或ty的数词 fifteen thirteen fifty thirty
fiftieth thirtieth fifteenth thirteenth
)\b#第二类数量结构
(?:\b\w+\b)#后跟的名词
""",re.VERBOSE)
这个式子到这里还是比较粗糙的,比如对于任何一文章中的“the one you”他都会当作数量结构匹配,所以还要增加一些其他条件来过滤这样的可能,不过我还没学到那个地步,所以我也没法解决这个问题,以后学会再来添加吧!更新一下:关键词:零宽断言。在python正则表达式中使用零宽断言,网上也有很多教程。简单说,零宽断言要完成的目标是:当字符串符合一定条件,则匹配某些字符。什么叫断言?一个断言就是对条件做出判断,相当于if判断结构,满足条件,则做某事,不过else只能是不匹配。什么叫零宽?也就是这个东西所占的匹配字符中的宽度是零,也就是不匹配本身。其他的关键词如零宽度正预测先行断言太复杂了我也不太清楚,就不讲了,会用就行。使用方法:exp(?=exp)在括号中使用?=后,这个括号内?=之后的字符就成了零宽断言所要判断的条件,前面括号之外的表达式则是判断满足条件要启用的匹配字符。举例:\w+(?=logy)该表达式匹配任意以logy结尾的单词,但是不匹配logy本身。如果要把这个判断放在前面,则要用:(?&=exp)exp举例:(?&=href=")http可以匹配href="开头的http,但是不包括href=",这样的操作也省去了爬虫清洗数据时的一部分压力。需要注意的是,前置的断言在python中不能使用不确定宽度的字符作为判断条件,必须确定字符的个数。所以如果你还想同时匹配(?&=src=")http,你不能写(?&=src="|href=")http,你可以写:(?:(?&=src=")|(?&=href="))http这是python实现的一个小缺陷。不过后置的就可以这么写http(?=src="|href=")接着我们还有满足条件不匹配的用法,也就是在?后面加!。前置的就成了(?!&=exp)后置的成了(?!=exp)这时候填写进去的字符,就成了遇到则不匹配的条件。而我的数词查找就需要这个功能,来实现避免数词出现在省略先行词从句的开头的情况。当然下面这个表达式是不能运行的,必须放到之前那个大串里。re.compile(r"""
(?:[Yy]ou|[Tt]hey)(?:'re)?
I|to|with|in|[SsHh]h?e|[Ii]t
(?:[Tt]h)(?:is|at|e[sr]e|)
(?:(?:[Ww]h)(?:o[ms]?e?|ere|at|en|i[cl][he]))
#筛掉的特殊词you I he she it this there that those with to in which where what when while whose who whom
""",re.VERBOSE)
结合两者就是:En_value = re.compile(r"""
#随时可以以#号备注
#尾断言可以有不确定符号数的匹配,首断言不可以。
(?:\b\w+\b\s\b\w+\b\s)?
(?:\ban?\b\s\b\w+\b\s\bof\b)
|#第一类数量结构
(?:\b(?:one|two|three|five|first|second|third|fifth|sixth|an?))
|#fifth在这里 没有规律的数词 fifth sixth
(?:(?:hundred|thounsand|million|billion|trillion|ten|eleven|twel(?:f|ve))(?:th)?)
(?:(?:twent|fort)(?:y|ieth))
(?:(?:four)(?:teen|th)?)
|#加不加teen皆可的数词
(?:(?:six|seven|eight?|nine?)(?:(?:(?:t[yh])(?:eth)?)|(?:teen)(?:th)?)?)
|#加不加teen或ty皆可的数词
(?:(?:fif|thir)(?:(?:t[yi])(?:eth)?|(?:teen)(?:th)?))
#必须加teen或ty的数词 fifteen thirteen fifty thirty
fiftieth thirtieth fifteenth thirteenth
)\b#第二类数量结构
(?:[Yy]ou|[Tt]hey)(?:'re)?
I|to|with|in|[SsHh]h?e|[Ii]t
(?:[Tt]h)(?:is|at|e[sr]e|)
(?:(?:[Ww]h)(?:o[ms]?e?|ere|at|en|i[cl][he]))
#筛掉的特殊词(you I he she it this there that those with to in which where what when while whose who whom
(?:\b\w+\b)#后跟的名词
""",re.VERBOSE)
好了这个问题的回答就完整了535 条评论分享收藏感谢收起python常见错误_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
python常见错误
&&初学python容易遇到的常见错误
阅读已结束,下载本文需要
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,同时保存到云知识,更方便管理
还剩6页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢}

我要回帖

更多关于 终端打开python文件 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信