我们在上一篇文章中已经学会了如何简单的运行python命令和脚本,但是,距离真正的写脚本还有一段距离。
为了防止我们写出来的脚本运行时报各种语法格式错误,我们需要在本章先学习下python的基本语法和脚本格式。
脚本声明
由于Python源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这两行:
# !/usr/bin/env python
# -*- coding:utf-8 -*-
或者
#coding:utf-8
第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,根据usr/bin/env路径去找python的运行程序来运行,Windows系统会忽略这个注释;
第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。
如果你使用Notepad++进行编辑,除了要加上# -- coding: utf-8 --外,中文字符串必须是Unicode字符串。
模块(类库)的引入
引入语句一般放在声明语句后面。
Python在语义中存在着包、模块、类(当然还有函数)这几个概念。
在编写Python代码时,我们需要管理代码的文件目录结构。
这时候会遇到这样一种情况:
1.由于Python一个文件算一个模块,一个带init.py的目录算一个包。
2.而为了控制代码文件不要过大,我们需要的是一个类(几个类或加些许函数)分配一个文件。
Python拥有一个强大的标准库。 Python语言的核心只包含数字、字符串、列表、字典、文件等常见类型和函数,而由Python标准库提供了系统管理、网络通信、文本处理、数据库接口、图形系统、XML处理等额外的功能。Python标准库命名接口清晰、文档良好,很容易学习和使用。
如引用,需import,如引入算数模块,系统模块
引入mysql数据库驱动
import math,os,sys
import MySQLdb
Python社区提供了大量的第三方模块,使用方式与标准库类似。它们的功能无所不包,覆盖科学计算、Web开发、数据库接口、图形系统多个领域,并且大多成熟而稳定。第三方模块可以使用Python或者C语言编写。SWIG,SIP常用于将C语言编写的程序库转化为Python模块。Boost C++ Libraries包含了一组库,Boost.Python,使得以 Python 或 C++ 编写的程序能互相调用。借助于拥有基于标准库的大量工具、能够使用低级语言如C和可以作为其他库接口的C++,Python已成为一种强大的应用于其他语言与工具之间的胶水语言。
引用自己写的模块则需要注意路径问题,现在有相对引用和绝对引用的说法,更多详情可查看。
一般来说自己需要引用所有的py文件放到调用它们的py文件同一目录下使用import即可。
例如我们有main.py文件和hapdbtools.py文件,放在同一目录如下:
hapdbtools.py文件声明了一个类DBtool内容如下:
#coding:utf-8
__author__ = "zzq"
import MySQLdb
import sys
class DBtool():
def __init__(self):
"""
获取数据库连接 __enter__函数配合with 使用 自动调用 enter 和 exit
:return:
"""
try:
self.__db = MySQLdb.connect(host="192.168.1.80", port=3306, db="test", user="zzq",
passwd="123456", charset="utf8")
self.__cursor = self.__db.cursor()
except MySQLdb.Error, e:
self.error_code = e.args[0]
error_msg = "MySQL error! ", e.args[0], e.args[1]
print error_msg
def __enter__(self):
"""
获取数据库连接 __enter__函数配合with 使用 自动调用 enter 和 exit
:return:
"""
self.__db = MySQLdb.connect(host="192.168.1.80", port=3306, db="test", user="zzq",
passwd="123456", charset="utf8")
self.__cursor = self.__db.cursor()
return self
def __exit__(self, type, value, traceback):
self.__db.close()
def query_data_by_barcode(self,barcode):
SQL_select_data="select data from mytable where barcode=%s"
self.__cursor.execute(SQL_select_data,barcode)
result=self.__cursor.fetchall()
#result=self.__cursor.fetchone()
if result:
return result
else:
return "none"
则main文件中引用时使用语句:
from hapdbtools import DBtool
调用方法时使用语句:
dbtools = DBtool()
result = dbtools.query_data_by_barcode(barcode)
print(result)
查看哪些脚本调用了hapdbtools脚本使用命令
grep hapdbtools *
注释
# 注释以 # 字符起始,直至实际的行尾;代码中注释不会被Python解释;文本字符串中的#仅表示#
# this is the first comment
SPAM = 1 # and this is the second comment
STRING = "# This is not a comment" # and this is the third comment
"""
前后三个单引号可进行多行注释
通常是对函数、对象的说明
注释代码仍以 # 为主
"""
赋值
# " = " 用于变量赋值;变量直接赋值,无须定义变量类型; 无须定义变量的数据类型
a = 20
#变量在使用前必须赋值,否则会出错
x = y = z = 1 # 可将同一个值赋给多个变量
在Python中,变量名没有类型,但对象有;变量名只是对对象的引用(内部实现为指针)
变量命名规则及惯例
语法: (下划线或字母)+(任意数目的字母、数字或下划线)
变量名必须以下划线或字母开头,而后面接任意数目的字母、数字或下划线。
区分大小写: SPAM和spam不同
禁止使用保留字
命名惯例:
以单一下划线开头的变量名(_X)不会被 from module import *语句导入
前后有下划线的变量名(_X_)是系统定义的变量名,对解释器有特殊意义
以双下划线开头,但结尾没有双下划线的变量名(__X)是类的本地(“压缩”)变量
通过交互模式运行时,只有单个下划线的变量名(_)会保存最后表达式的结果
简单的输入、输出
# 简单的输入输出
raw_input("Please input: ") # Python2.x raw_input()
input("Please input: ") # Python3.x input()
print "hello world" # Python2.x 可以不用加()
print("hello world") # Python3.x 必须要加(),不然会报错! Python3.x print() 会是空行,而Python2.x print() 则会显示(),须注意!
print("This is "Note"") # 该条报错!需对"转义
关于特殊字符及Unicode
# 关于特殊字符及Unicode
print("This is "Note"") # 转义
print("This isnNote") # n 换行
print ("Hello"+u"u0020"+"World") # u"xxxx":Python2.x unicode对象 = 直接在字符串前加u关键字
print("Hellou0020World") # Python2.x 直接输出 Hellou0020World ,Python3.x 会输出 Hello World
字符串双引号等特殊字符需转义,转义的方法是在 前面加上; n 表示换行
从Python 3.0开始所有的字符串都支持Unicode(参考 )
Unicode 的先进之处在于为每一种现代或古代使用的文字系统中出现的每一个字符都提供了统一的序列号。之前,文字系统中的字符只能有 256 种可能的顺序。通过代码页分界映射。文本绑定到映射文字系统的代码页。这在软件国际化的时候尤其麻烦(通常写作 i18n —— ’i’ + 18 个字符 + ’n’ )。Unicode 解决了为所有的文字系统设置一个独立代码页的难题。
语法规则
a,b = 0,1 # 变量也可这么赋值,但不建议
while b < 30:
print(b)
a,b = b,a+b # 相当于 a=b 和 b = a+b
需要注意的是:缩进
Python开发者有意让违反了缩进规则的程序不能通过编译,以此来强制程序员养成良好的编程习惯。并且Python语言利用缩进表示语句块的开始和退出(Off-side规则),而非使用花括号或者某种关键字。增加缩进表示语句块的开始,而减少缩进则表示语句块的退出。缩进成为了语法的一部分。同样的如 if 语句如下:
根据PEP的规定,必须使用4个空格来表示每级缩进(不清楚4个空格的规定如何,在实际编写中可以自定义空格数,但是要满足每级缩进间空格数相 等)。使用Tab字符和其它数目的空格虽然都可以编译通过,但不符合编码规范。支持Tab字符和其它数目的空格仅仅是为兼容很旧的的Python程序和某些有问题的编辑程序。
不缩进会报错的例子
a = 2
if a>1:
print("a>1") # if 无执行语句会报错,若需实现if条件下print,参考如下
缩进不对导致if语句无效的例子
a = 0
if a>1:
print("a>1")
print("a!=1") # 该语句始终会执行,因为缩进并不在if条件下
缩进不对导致if语句无效不会报错,非常容易坑人,改为以下层次if条件生效:
a = 0
if a>1:
print("a>1")
print("a!=1") # 该语句仅if成立条件下执行
更多格式问题参考:
控制语句
if语句,当条件成立时运行语句块。经常与else, elif(相当于else if) 配合使用。 for语句,遍历列表、字符串、字典、集合等迭代器,依次处理迭代器中的每个元素。 while语句,当条件为真时,循环运行语句块。 try语句。与except,finally配合使用处理在程序运行中出现的异常情况。 class语句。用于定义类型。 def语句。用于定义函数和类型的方法。 pass语句。表示此行为空,不运行任何操作。 assert语句。用于程序调适阶段时测试运行条件是否满足。 with语句。Python2.6以后定义的语法,在一个场景中运行语句块。比如,运行语句块前加密,然后在语句块运行退出后解密。 yield语句。在迭代器函数内使用,用于返回一个元素。自从Python 2.5版本以后。这个语句变成一个运算符。 raise语句。制造一个错误。 import语句。导入一个模块或包。 from import语句。从包导入模块或从模块导入某个对象。
import as语句。将导入的对象赋值给一个变量。
in语句。判断一个对象是否在一个字符串/列表/元组里。
数据结构
Python采用动态类型系统。在编译的时候,Python不会检查对象是否拥有被调用的方法或者属性,而是直至运行时,才做出检查。所以操作对象时可能会抛出异常。不过,虽然Python采用动态类型系统,它同时也是强类型的。Python禁止没有明确定义的操作, 比如数字加字符串。 与其它面向对象语言一样,Python允许程序员定义类型。构造一个对象只需要像函数一样调用类型即可。类型本身也是特殊类型type的对象(type类型本身也是type对象),这种特殊的设计允许对类型进行反射编程。
Python内置丰富的数据类型。与Java、C++相比,这些数据类型有效地减少代码的长度。下面这个列表简要地描述了Python内置数据类型(适用于Python 3.x):
除了各种数据类型,Python语言还用类型来表示函数、模块、类型本身、对象的方法、编译后的Python代码、运行时信息等等。因此,Python具备很强的动态性。
类型 描述 例子 备注
str 一个由字符组成的不可更改的类型 “joe” 在python3里,字符串由Unicode字符组成
bytes 一个由字节组成的不可更改的类型 b = b”joe”
list 可以包含多种类型的可改变的类型 [4.0,”joe”,True]
tuple 可以包含多种类型的不可改变的类型 {4.0,”joe”,True}
set,frozenset 与数学集合的概念类型,无序,每个元素唯一 {4.0,”joe”,True},frozenset()
dict 一个可改变的由键值对组成的类型 {4.0,”joe”,True}
int 精度不限的整数 66
float 浮点数,精度与系统相关 3.1415927
complex 复数 3+2.7j
bool 逻辑值,真假 True,False
表达式
+, -, *, /, //, **, ~, %分别表示加法或者取正、减法或者取负、乘法、除法、整除、乘方、取补、取模。
>>, <<表示右移和左移。
&, |, ^表示二进制的AND, OR, XOR运算。
>, <, ==, !=, <=,>=用于比较两个表达式的值,分别表示大于、小于、等于、不等于、小于等于、大于等于。
在这些运算符里面,~, |, ^, &, <<,>>必须应用于整数。
使用and, or, not表示逻辑运算
区分列表(list)和元组(tuple)两种类型;支持列表切割(list slices)
一些Python特有的方法,如 range() lambda 等
函数
Python的函数支持递归、默认参数值、可变参数,但不支持函数重载。为了增强代码的可读性,可以在函数后书写“文档字符串”(Documentation Strings,或者简称docstrings),用于解释函数的作用、参数的类型与意义、返回值类型与取值范围等。可以使用内置函数help()打印出函数的使用帮助。比如: help(randint)
# 函数示例
def my_fun1():
print("hi")
my_fun1() # 调用函数
def my_fun2(a): # 函数可带参数, 参数可为多个
if(a>2):
print(">2")
my_fun2(3)
对象
# 对象示例
class User(object): # Python2.x 需在()内加object;Python3.x 不用加object
def __init__(self,name): # 类似于构造函数
self.name=name
def print_name(self):
print(self.name)
u = User("John") # u为一 User对象
print(u.name) # 输出对象属性
User.print_name(u) # 调用print_name()函数