giun

  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

Nginx + Lua 搭建网站WAF防火墙

发表于 2020-06-17 | 分类于 web

@TOC

一、目的

利用centos -7 和Nginx + Lua 搭建网站WAF防火墙可以防御SQL、XSS等攻击。

二、前期环境准备

(一)、更新下yum源

这边使用的是centos-7的系统,这边采用清华源

1
2
[root@wr ~]# mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
[root@wr ~]# vi /etc/yum.repos.d/CentOS-Base.repo.repo

在这里插入图片描述
更新软件包缓存

1
[root@wr ~]# yum makecache

在这里插入图片描述

(二)、编译安装Nginx

先编译安装一下,后面说lua模块的时候再重新编译下就行了

下载相应的包:curl -o nginx.tar.gz http://nginx.org/download/nginx-1.16.0.tar.gz

解压:tar -zxvf nginx.tar.gz
进入到nginx-1.16.0目录(nginx 压缩目录),进行编译参数的配置

1
cd nginx-1.16.0

然后编译参数命令

1
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'

可以使用nginx -V来查看编译参数
最后进编译安装

1
make && make install

(三)、端口放行

因为我们要通过http访问,所以要方向80端口
开发80端口

1
[root@wr ~]# firewall-cmd --zone=public --add-port=80/tcp --permanent

使得新建的规则生效

1
[root@wr ~]# firewall-cmd --reload

在这里插入图片描述

(四)、验证安装

设置开机启动nginx

1
[root@wr ~]# systemctl enable nginx

启动nginx

1
[root@wr ~]# systemctl start nginx

查看nginx是否启动

1
[root@wr ~]# ps -aux |grep nginx

在这里插入图片描述
在另一台机器上验证,成功安装
在这里插入图片描述

(五)、lua编译安装

1、安装Lua库

1
[root@wr ~]# yum install lua lua-devel -y

在这里插入图片描述
2、安装下载Lua即使编辑器、

1
[root@wr ~]# wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz

3、下载Nginx模块:ngx_devel_kit and lua-nginx-module

1
2
[root@wr ~]# wget https://github.com/simplresty/ngx_devel_kit/archive/v0.3.1.tar.gz
[root@wr ~]# wget https://github.com/openresty/lua-nginx-module/archive/v0.10.15.tar.gz

在这里插入图片描述
4、编译安装luajit并导入环境变量
解压

1
2
3
[root@wr ~]# tar -zxf v0.3.1.tar.gz 
[root@wr ~]# tar -zxf v0.10.15.tar.gz
[root@wr ~]# tar -zxf LuaJIT-2.0.5.tar.gz

在这里插入图片描述
编译安装

1
2
[root@wr ~]# cd LuaJIT-2.0.5
[root@wr LuaJIT-2.0.5]# make install RREFTX=/usr/local/LuaJIT

在这里插入图片描述
发现报错,确实gcc命令,安装该命令,然后再次编译安装
在这里插入图片描述
在这里插入图片描述
导入环境变量

1
2
export LUAJIT_LIB=/usr/local/LuaJIT/lib
export LUAJIT_INC=/usr/local/LuaJIT/include/luajit-2.0

在这里插入图片描述
加载lua库到ld.so.conf文件

1
[root@wr ~]# echo "/usr/local/LuaJIT/lib" >> /etc/ld.so.conf

在这里插入图片描述
查看是否加载成功

1
[root@wr ~]# cat /etc/ld.so.conf

在这里插入图片描述
然后在nginx-1.60目录下执行一下命令,让动态函数加载到缓存中

1
[root@wr nginx-1.16.0]# ldconfig

5、配置nginx编译参数及重新编译安装nginx

6、验证lua是否可以使用
在nginx.config的server节点下添加:

1
vi /etc/nginx/nginx.conf

在这里插入图片描述
然后使得配置命令生效
检查配置

1
nginx -t -c /etc/nginx/nginx.conf

配置生效

1
nginx -s reload -c /etc/nginx/nginx.conf

开始验证,如果出现404错误,重启centos即可解决问题
在这里插入图片描述

三、Nginx+Lua搭建WAF防火墙

这边使用开源的ngx_lua_waf来进行搭建

(一)、php环境配置

参考链接
安装php-fpm

1
yum install php-fpm

在nginx.conf的配置。只需要把loaction /php 里的注释符号去掉即可
还有一个问题就是fastCGI参数SCRIPT_FILENAME 是写死的。如果修改了root指令的值或者移动文件到别的目录,php-fpm会返回“No input file specified”错误,因为SCRIPT_FILENAME在配置中是写死的并没有随着$doucument_root变化而变化,我们可以修改SCRIPT_FILENAME配置如下:fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

在根目录下面。创建一个文件名为index.php文件,内容为<?php phpinfo(); ?>
在这里插入图片描述

(二)、克隆代码并将其移动到nginx/waf目录下

1
2
3
[root@wr nginx-1.16.0]# git clone https://github.com/loveshell/ngx_lua_waf
[root@wr ngx_lua_waf]# mkdir /etc/nginx/waf
[root@wr ngx_lua_waf]# mv * /etc/nginx/waf/

在这里插入图片描述
参数说明:
1、args里面的规则get参数进行过滤的
2、url是只在get请求url过滤的规则
3、post是只在post请求过滤的规则
4、whitelist是白名单,里面的url匹配到不做过滤
5、user-agent是对user-agent的过滤规则

(三)、进行必要配置

1
[root@wr waf]# vi config.lua

如果有个目录不存在可以自己使用mkdir命令创建.,这边白名单加一个服务器本机的IP,然后规则存放目录应该是/etc/nginx/waf/wafconf。下图有误。
在这里插入图片描述
在nginx.config的http下添加如下内容

1
vi /etc/nginx/nginx.conf

在这里插入图片描述

1
2
3
4
lua_package_path "/etc/nginx/waf/?.lua";
lua_shared_dict limit 10m;
init_by_lua_file /etc/nginx/waf/init.lua;
access_by_lua_file /etc/nginx/waf/waf.lua;

(四)、验证

添加一个在args中sql规则\sor\s+,然后
重启服务

1
[root@wr waf]# nginx -s reload -c /etc/nginx/nginx.conf

在根目录下创建一个名为test.php文档,内容为<?php echo $_GET['id']; ?>
xss防御
在这里插入图片描述
sql防御
在这里插入图片描述

四、总结

在centos 7系统下配置Nginx+lua基本上都需要编译安装和配置,会比较繁琐一下,不过在线安装容易出错。在配置防火墙规则的时候注意白名单和规则目录的配置,没配置好的话。很难找出问题。特别是白名单。

Python知识整合(操作数据库)

发表于 2019-09-12 | 分类于 python

1、数据库编程接口

市面有多种数据库如mysql、SQLite等等。为了对数据库进行统一的操作,大多数语言提供了简单的、标准化的数据库接口(API)。在Python Database API 2.0规范中,定义了Python数据库API接口的各个部分。下面我将介绍数据库API接口中的连接对象和游标对象

1.1、连接对象

数据库连接对象(Connection Object)主要提供数据库游标对象和提交/回滚事物的方式,以及关闭数据库连接。

1.11、获取连接对象

使用connect()函数获取数据库连接,改函数具有多个参数,具体使用那个参数,根据数据库的类型而定。

onnect()函数参数说明表

参数 说明
dsn 数据源名称,给出该参数表示数据库依赖
user 用户名
password 用户密码
host 主机名
database 数据库名称

例子,使用PyMySql模块连接MySQL数据库(在下面内容中会详细介绍)。

conn = pymysql.connect(host='localhost', 
                        user='user',
                        password='passwd',
                        charset='utf-8'
                        cursorclass=pymysql.cursors.DictCursor)

注意pymysql.connect()使用的参数与上表不完全相同,要以具体的数据库模块为准。

1.12、连接对象方法

connect()函数返回连接对象,这个连接对象表示目前和数据库的会话。连接对象支持的方法如下表
| 方法名 | 说明 |
| ———- | ———————————————————— |
| close() | 关闭数据库连接 |
| commit() | 提交事物 |
| rollback() | 回滚事物 |
| cursor() | 获取游标对象,操作数据库,如执行DML(触发器)操作,调用存储过程等 |

1.2、游标对象

游标对象(Cursor Object)代表数据库中的游标,用于指示抓取数据操作的上下文,主要提供执行SQL语句、调用存储过程等。

通过cursor()方法可以获取游标对象。

游标对象的属性:1、description:数据库列表类型和值的描述信息。2、rowcount():返回结果的函数统计信息,如SELECT、UPDATE等

游标对象的方法如下表
| 方法名 | 说明 |
| ———————————- | ———————————————————— |
| callproc(procname[,parameters]) | 调用存储过程,需要数据库支持 |
| close() | 关闭当前游标 |
| execute(operation[,parameters]) | 执行SQL语句或者数据库命令等数据库操作 |
| executemany(operation,seq_params) | 用于批量操作,如批量删除 |
| fetchone() | 获取查询结果集中的下一条记录 |
| fetchmany(size) | 获取指定数量的记录 |
| fetchall() | 获取结果集中的所有记录 |
| nextset() | 跳至下一个可用的结果集 |
| arraysize() | 指定使用fetchmany获取的函数,默认为1 |
| setinputsize(sizes) | 设置在调用execute*()方法时分配的内存区域大小 |
| setoutputsize(sizes) | 设置列缓冲区大小,对大数据列如LONGS和BLOBS(二进制大对象)尤其有用 |

2、使用SQLite

SQLite(c语言写的)是一种嵌入式数据库,它的数据库是一个文件。体积小,且可以跨平台使用,经常被嵌入到各种应用程序。python中内置了SQLite3。

2.1、创建数据库文件

python操作数据流的流程

开始>>创建connection(连接)>>获取cursor(游标)>>执行SQL语句,处理数据结果>>关闭cursor(游标)>>关闭connection(连接)

​
如

import sqlite3   # 连接到SQLite数据库
conn = sqlite3.connect('1.db')   # 数据库文件是test.db,如果文件不存在,会在当前目录创建
cursor = conn.cursor()  # 创建一个Cursor
cursor.execute('create table user (id int(10) primary key, name varchar(20))')  # 执行一条SQL操作,创建user表
cursor.close()  # 关闭游标
conn.close()  # 关闭连接

2.2、操作SQLite

2.21、新增用户数据信息

使用以下SQL语句

insert into 表名 (字段名1,字段名1,........) values(字段值1,字段值2,.......)

例子

import sqlite3   # 连接到SQLite数据库
conn = sqlite3.connect('name.db')   # 数据库文件是test.db,如果文件不存在,会在当前目录创建
cursor = conn.cursor()  # 创建一个Cursor
# 执行一条SQL操作,创建user表
cursor.execute('create table user (id int(10) primary key, name varchar(20))')
# 执行一条SQL操作,向表user插入一条记录
cursor.execute('insert into user (id, name) values ("1","wr")')
cursor.execute('insert into user (id, name) values ("2","小明")')
cursor.close()  # 关闭游标
conn.commit()  # 提交事物
conn.close()  # 关闭连接

为了验证程序是否正常可以再次运行程序,如果出现如下异常

sqlite3.OperationalError: table user already exists

则说明数据成功插入

2.22、查看用户数据信息

可以使用以下SQL语句

select 字段名1,字段名2,..... from 表名 where 查询条件

fetchone():查询结果集中的下一条记录
fetchmany(size) :获取指定数量的记录
fetchall():获取结果集的所有记录

例子

import sqlite3   # 连接到SQLite数据库
conn = sqlite3.connect('name.db')   # 数据库文件是name.db,如果文件不存在,会在当前目录创建
cursor = conn.cursor()  # 创建一个Cursor

# 执行查询语句
cursor.execute('select * from user') 
# 获取查询结果
result = cursor.fetchone()
print(result)

cursor.close()  # 关闭游标
conn.close()  # 关闭连接

修改上述 cursor.execute('select * from user') 这句代码为cursor.execute('select * from user where id > ?',(1,)),其中使用问号作为占位符代替具体的值,然后使用最后一个元组来替换问号,注意元组最后面的逗号不能省略
修改后的代码等价于cursor.execute('select * from user where id > 1)
不过推荐占位符的方式,因为可以有效防止SQL注入

2.23、修改用户数据信息

可以使用以下sql语句

update 表名 set 字段名 = 字段值 where 查询语句

例子,将ID=1的name改为WR

import sqlite3   # 连接到SQLite数据库
conn = sqlite3.connect('name.db')   # 数据库文件是test.db,如果文件不存在,会在当前目录创建
cursor = conn.cursor()  # 创建一个Cursor

cursor.execute('update user set name = ? where id = ?', ('WR', 1))
# 执行查询语句
cursor.execute('select * from user')
# 获取查询结果
result1 = cursor.fetchall()
print(result1)

cursor.close()  # 关闭游标
conn.commit() # 提交事务
conn.close()  # 关闭连接

2.24、删除用户信息

可以使用以下sql语句

delete from 表名 where 查询语句

3、使用MySQL

可以直接安装phpstudy集成环境,包括mysql和apache数据库及其环境。安装步骤可以百度

3.1、安装PyMySQL模块

在python中支持MYSQL的数据库模块很多,我们选择PyMySQL模块
在命令行使用下面语句 pip install PyMySQL安装PyMySQL模块

3.2、连接数据库

PyMySQL模块也遵循Python Database API 2.0规范,故MySQL的操作方法与SQLite类似
例子

import pymysql

# 打开数据库连接,参数1:主机名或IP;参数2:用户名;参数3:密码;参数4;数据库名称
db = pymysql.connect("localhost", "root", "root", "mydata")
# 通过cursor()函数创建一个游标对象cursor
cursor = db.cursor()
# 使用execute()方法执行SQL查询
cursor.execute('SELECT VERSION()')
# 使用 fetchone()方法获取单条信息
data = cursor.fetchone()
print("database version: %s" % data)
# 关闭数据库连接、
db.close()

输出

database version: 5.5.53

3.3、创建数据表

例子:通过execute()方法创建表books(图书表)。books包含id(主键),name(图书名),category(图书馆分类),price(图书馆价格)

import pymysql

# 打开数据库连接,参数1:主机名或IP;参数2:用户名;参数3:密码;参数4;数据库名称
db = pymysql.connect("localhost", "root", "390800956", "mydata")
# 通过cursor()函数创建一个游标对象cursor
cursor = db.cursor()
# 使用execute()方法执行SQL语句,如果存在就删除
cursor.execute('DROP TABLE IF EXISTS books')
sql = """
CREATE TABLE books(
    id int(8) NOT NULL AUTO_INCREMENT,
    name varchar(50) NOT NULL,
    category varchar(50) NOT NULL,
    price decimal(10,2) DEFAULT NULL,
    PRIMARY KEY (id)   
)   ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
"""
cursor.execute(sql)

# 关闭数据库连接、
db.close()

3.4、操作数据表

可以execute()方法添加一条记录,也可以使用executemany()方法进行批量添加记录
语法格式

executemany(operation,seg_of_params)

说明:
operation:执行的sql语句
seg_of_params:参数序列

例子

import pymysql

# 打开数据库连接,参数1:主机名或IP;参数2:用户名;参数3:密码;参数4;数据库名称
db = pymysql.connect("localhost", "root", "390800956", "mydata", charset="utf8")
# 通过cursor()函数创建一个游标对象cursor
cursor = db.cursor()
# 数据列表
data = [("《见识》", "literature", "50.00"),
        ("《智能时代》", "data", "70.00"),
        ("《活着》", "literature", "23.00")]
try:
    # 执行SQL语句,插入多条数据
    cursor.executemany("insert into books (name, category, price) values (%s, %s, %s)", data)
    # 提交数据
    db.commit()
except:
    # 发送错误时回滚
    db.rollback()
# 关闭数据库连接、
db.close()

在上面的代码中要注意
1、在使用connect()方法时,设置charset=”utf8”,为得是识别中文
2、在使用insert语句插入数据时,使用%s作为占位符,防止SQL注入

python知识整合(文件及目录操作)

发表于 2019-09-12 | 分类于 python

1、基本的文件操作

python中内置了文件(fFle)对象,使用文件对象的大概流程如下:
1、创建文件(通过内置open()函数)
2、通过该对象提供的方法进行一些基本的文件操作,如write()、close()等方法

1.1、创建和打开文件

可以通过open()方法实现
语法格式:

file = open(filename[,mode[,buffering]])

说明:
file:为被创建的文件对象
filename:要创建或者打开的文件名,可以使用绝对路径和相对路径
mode:可选参数,用于指定文件的打开模式,默认打开模式为只读(r)
buffering: 可选参数,用于指定读写文件的缓存模式,值为0表示不缓存,1表示缓存,大于1表示缓冲区的大小,默认为读写模式

1.11、当打开不存在的文件,会抛出异常,解决办法有

1、创建该文件
2、在调用open()函数时,指定mode的参数值为w、w+、a、a+。这样的话,如果要打开的文件不存在就会自动创建新文件,归根到底还是和第一钟方法相联系

1.12、以二进制的形式打开文件

open()函数不仅可以以文本形式打开文件,还可以以二进制形式打开文件,只要将mode参数设置为rb、 rb+、 wb、 wb+、 ab 、ab+,就可以

如

file = open('1.jpg', 'rb')
print(file)

输出

<_io.BufferedReader name='1.jpg'>

可以看出创建的是一个BufferedReader(缓冲区读取)对象,该对象生成后我们可以使用第三方模块进行处理,如PIL的Image模块。

1.13、 打开文件时指定编码方式

open()方法打开文件时,默认为GBK编码,如果被打开的文件的编码不是GBK那么会抛出异常

解决方法
1、直接修改文件的编码
2、打开文件时,指定使用的编码方式(推荐)。在使用open函数打开文件时,使用encoding= ‘编码方式’,指定编码方式。

如,打开采用UTF - 8编码保存的文件1.txt

file = open('1.txt1','r',encoding= 'utf -8')

1.2、关闭文件

文件打开后,使用完要及时关闭文件。可以使用close()方法
语法格式

file.close()

说明:close()方法会先刷新缓冲区中未写入的数据,然后再关闭文件。这样可以将未写入文件的数据写入文件。文件关闭后,不能再进行写操作

1.3、打开文件时使用with语句

如果在打开文件时如果抛出了异常,那么可能无法及时关闭文件。我们可以使用with语句避免这个问题
语法格式:

with expression as target
    with_body

参数说明:
expression:用于指定一个表达式,这边可以是open()函数
target: 用于指定一个变量,并将expression的结果保存到该变量里
with-body:用于指定with语句体,其中可以是执行with语句后的相关一些操作语句,也可以是pass

如

with open('1.jpg', 'rb') as file:
    pass

1.4、写入文件内容

使用write()函数
语法格式

file.write(string)

部分参数说明:
string为要写入的字符串

使用write()方法的前提是,在打开文件时,指定的打开模式为w(可写)或者a(追加)等等

1.5、读取文件

读取文件主要分为以下3种情况。

1.51、读取指定字符串

1、从头开始读取文件内容
使用read()方法,语法格式

file.read([size])     #size用于指定要读取的字符个数,如果省略,则一次性读取全部

例子,注意打开模式只能为r或者r+

with open('2.txt', 'r+') as file:
    print(file.read(2))

2、读取部分内容
使用seek()方法将指针移动到新的位置,再用read(size)方法读取。seek()基本语法

file.seek(offset[,whence])

部分参数说明
offset:用于指定移动的字符个数,其具体位置与whence有关
whence:用于指定从什么位置开始算。0表示从文件头开始计算,1表示当前位置,2表示文件尾,默认为0。
注意
如果在打开文件时,没有使用b模式,那么只允许从文件头开始计算,从文件尾会报错。
使用seek()方法时,offset的值是一个汉字占2个字符,一个数字或者英文占一个字符,与read()方法不同。

例子

with open('2.txt', 'r') as file:
    file.seek(3)
    print(file.read(2))

1.52、读取一行

使用readline()方法,语法格式

file.readline()

文件的打开模式要求与使用read()方法一样
例子,一行一行输出2.txt里的内容

with open('2.txt', 'r', encoding="utf-8") as file:
    number = 0  # 记录行号
    while True:
        number += 1
        line = file.readline()
        if line == '':
            break
        print(number, line)  # 输出一行的内容

1.53、读取全部行

使用readlines()方法,语法格式

file.readlines()        # 返回类型为字符串列表

例子:
2.txt文件内容为
学无止境
python有趣
好好学习
天天向上

with open('2.txt', 'r', encoding="utf-8") as file:
    print(file.readlines())

输出

['学无止境\n', 'python有趣\n', '好好学习\n', '天天向上']

可以看出返回一个字符串列表,但是如果文件比较大,这种方法效率太低,这时可以将列表内容逐行输出,修改后的代码为

with open('2.txt', 'r', encoding="utf-8") as file:
    a = file.readlines()
    for i in a:
        print(i)

2、目录操作

python中并没有直接提供操作目录的函数或者对象,而是通过内置的os和os.path模块实现。

其中os模块是python内置的与操作系统功能和文件系统相关的模块,该模块上执行结果通常与操作系统有关,在不同的操作系统上执行可能会有不同的效果
这边的操作系统为windows系统

2.1、os和os.path模块

要使用os和os.path模块 ,首先要使用import语句导入,代码如下

import os

导入os模块后,也可以使用其子模块os.path
os模块提供的常用的变量有以下几个
1、name:用于获取操作系统类型
如

import os
print(os.name)

输出

nt             # nt为windows系统,posix为Linux、UNIX或者Mac OS操作系统

2、linesep:用于获取当前操作系统的换行符

3、sep:用于获取当前存在系统的路径分隔符

os模块提供的与目录相关的函数
| getcwd() | 返回当前的工作目录 |
| ——————————– | ———————————————————— |
| listdir(path) | 返回指定路径下的文件和目录信息 |
| mkdir(path [,mode]) | 创建目录 |
| kakedirs(path1/path2/……..) | 创建多级目录 |
| rmdir(path) | 删除目录 |
| removedirs(path1/path2/……..) | 删除多级目录 |
| chdir(path) | 把path设置为当前工作目录 |
| walk(top [,topdown[,onerror]]) | 遍历目录树,该方法返回一个元组,包括所有路径名、所有目录列表和文件列表3个元素 |

os.path模块提供的与目录相关的函数
| 函数 | 说明 |
| —————- | ————————————————– |
| abspath(path) | 用于获取文件或目录的绝对路径 |
| exists(path) | 用于判断路径是否存在,存在返回True,不存在返回False |
| join(path,name) | 将目录与目录或者与文件名拼接起来 |
| splitext() | 分离文件名和扩展名 |
| basename(path) | 从一个目录中提取文件名 |
| dirname(path) | 从一个路径中提取文件路径,不包括文件名 |
| isdir(path) | 用于判断是否为路径 |

2.2、路径

1、包括绝对路径和相对路径

2、可以使用os模块提供的getcwd()函数获取当前工作目录
代码如下

import os
print(os.getcwd())   

在python中,指定文件路径时要对路径分隔符进行“\”转义,即将路径分隔符

“\”替换为”\“。也可以用“/”代替。

3、拼接目录
使用os.path.join()函数进行拼接,
语法格式为

os.path.join(path1 [,path2[,.......]])

(1)、path1、path2为要拼接的路径,如果要拼接的路径中没有一个是绝对路径那么拼接出来的路径就是相对路径。
(2)、使用 os.path.join()拼接路径时,并不会检测该路径是否真实存在
如

import os
print(os.path.join("E:\\Pyth", "web\\ 1.txt"))

输出

E:\Pyth\web\ 1.txt

在使用os.path.join()函数时,如果要拼接的路径中有多个绝对路径,那么以从左到右最后一次出现的为准,之前的参数会被忽略,如
import os

print(os.path.join("E:\\Pyth", "D:\\txt" , "demo"))

输出

D:\txt\demo

注意:2个路径要拼接在一起时,不要直接使用字符串拼接,而是使用os.path.join()函数,这样可以处理不同操作系统的分隔符。

2.3、判断目录是否存在

使用os.path.exists()函数,语法格式如下

os.path.exists(path)

路径存在返回True,不存在返回False,path可以为绝对路径或者相对路径,该函数还可以判读文件算法存在

2.4、创建目录

2.41、创建一级目录

使用os.mkdir()函数创建目录,该函数只能创建一级目录,也就是知道路径的最后一级目录,如果该目录的上一级目录不存在,则会抛出异常,如果要创建的路径已经存在也会抛出异常
语法格式

os.mkdir(path,mode= 0o777)

mode用于指定数值的模式,默认值为0777,该参数在非UNIX系统时无效或者被忽略
如,创建一个C:\demo目录(windows系统)

import os
os.mkdir("C:\\demo")

那如何避免上面所说的创建的路径已经存的问题呢。可以使用以下代码,先判断,再创建

import os
path = "C:\\demo"
if not os.path.exists(path):       # 判断目录是否存在
    os.mkdir(path)
    print("创建目录成功")
else:
    print("目录已经存在")

2.42、创建多级目录

使用os.makedirs()函数,语法格式

os.makedirs(name, mode = 0o777)

name:用于指定要创建目录
例子
在windows系统上创建一个多级目录

import os
path = "C:\\demo\\web\\mr"
os.makedirs(path)

2.5、删除目录

通过os.rmdir()函数可以删除目录,且要删除的目录为空时才有效,语法格式


os.rmdir(path)

如

import os
path = "C:\\Desktop\\web"
os.rmdir(path)

删除后的目录

C:\Desktop\web

如果目录不存在会抛出异常,将代码进行改进

import os
path = "C:\\Desktop\\web"
if os.path.exists(path):
    os.rmdir(path)
    print("目录成功删除")
else:
    print("该目录不存在")

注意:
os.rmdir()函数只能删除空目录,如果要删除非空目录,可以使用python中内置模块shutil的rmtree()函数实现。
如,删除不为空的目录C:\Desktop\web

import shutil
shutil.rmtree("C:\\Desktop\\web")

2.6、遍历目录

使用os.walk()函数,语法如下

os.walk(top [, topdown] [,onerror] [,follwlinks])

参数说明
top:用于指定要遍历的内容的根目录

topdown:可选参数用于指定遍历的顺序,值为True就是自上而下的遍历(从根目录开始),如果值为False就是自下而上的遍历。默认为True

onerror: 可选参数,用于指定错误处理方式,默认忽略,也可以指定一个错误处理函数,一般采用默认

followlinks: 可选参数,在默认情况下,walk()函数不会向下转换成解析到目录的符号链接。将该参数值设置为True,表示用于在支持的系统上访问由符号链接指向的目录

返回值: 返回3个元素(dirpath、dirnames、filenames)的元组生成器对象。dirpath表示当前遍历的路径,是一个字符串;dirnames表示当前路径下包含的子目录,是一个列表,filenames表示当前路径下包含的文件,是一个列表

如,遍历D:\Python\web目录

import os
# 遍历D:\Python\web目录
tuples = os.walk("D:\\Python\\web")
for tuplel in tuples:    # 通过for循环输出遍历结果
    print(tuplel, '\n')

注意:walk()函数只在windows系统和UNIX系统中有效。

3、文件的高级操作

os模块中与文件相关的函数
| 函数 | 说明 |
| —————————- | ———————————————————— |
| access(path,accessmode) | 获取对文件是否有指定的访问权限(读取,写入,执行权限)。accessmod的值是R_OK(读取)、W_OK(写人)、X_OK(执行)或F_OK(存在)。如果有指定的权限,则返回1,否则返回0 |
| chmod(path,mode) | 修改path指定文件的访问权限 |
| remove(path) | 删除path指定的文件路径 |
| rename(src,dst) | 将文件或目录src重命名为dst |
| stat(path) | 返回path指定文件的信息 |
| startfile(path [,operation]) | 使用关联的应用程序打开path指定的路径 |

3.1、删除文件

使用os.remove()函数,语法格式

os.remove(path)

如,删除当前目录下的2.txt文件,代码如下

import os
path = "2.txt"               # 使用相对路径(绝对路径也可以),要删除的文件
if os.path.exists(path):     # 判断文件是否存,防止文件不存在时抛出异常
    os.remove(path)
    print("文件删除成功")
else:
    print("该文件不存在")

3.2、重命名文件和目录

使用os.rename()函数,如果指定的路径是文件,则重命名文件,如果是目录,则重命名目录,语法格式

os.rename(src,dst)

例子:将当前目录下的2.txt重命名为1.txt

import os
src = "D:\\Python\\web\\2.txt"
dst = "D:\\Python\\web\\1.txt" # 使用绝对路径(相对路径也可以),要删除的文件
if os.path.exists(src):     # 判断文件是否存
    os.rename(src, dst)
    print("文件重命名成功")
else:
    print("该文件不存在")

值得注意的是使用rename()函数重命名目录时操作与重命名文件一样,但是只能修改最后一级的目录名称,否则会抛出异常。

3.3、获取文件的基本信息

通过os.stat()函数可以获取文件的基本信息,语法格式如下

os.stat(path)

start()函数返回式的对象的常用属性
| 属性 | 说明 | 属性 | 说明 |
| ——– | ———————— | ——– | ———————————————————— |
| st_mode | 保护模式 | st_dev | 设备名 |
| st_ino | 索引号 | st_uid | 用户ID |
| st_nlink | 硬连接号(被连接的数目) | st_gid | 组ID |
| st_size | 文件大小,单位为字节 | st_atime | 最后一次询问时间 |
| st_mtime | 最后一次修改时间 | st_ctime | 最后一次状态变化的时间(不同系统不一样,如windows系统返回的是问卷创建的时间) |

4、牛刀小试

1、查找特定目录D:\Python\web下以m开头的文件

import os, re
input_dir = os.walk("D:\\Python\\web")
for dirPath, dirNames, fileNames in input_dir:     # 根据os.walk输出目录信息
        for fileName in fileNames:                # 对文件列表进行遍历
            pattern = r'^m+'                      # 模式字符串
            match = re.match(pattern, fileName)    # 查找匹配条件的文件名
            if match:              # 判断是否匹配成功
                print(os.path.join(dirPath, fileName))    # 拼接目录和文件名,并输出

或者

import os, re
input_dir = input("please input the search dir:")
for dirPath, dirNames, fileNames in os.walk(input_dir):     # 根据os.walk输出目录信息
        for fileName in fileNames:                # 对文件列表进行遍历
            pattern = r'^m+'                      # 模式字符串
            match = re.match(pattern, fileName)    # 查找匹配条件的文件名
            if match:              # 判断是否匹配成功
                print(fileName)
                print(os.path.join(dirPath, fileName))    # 拼接目录和文件名,并输出

2、复制C盘下的1.log文件到你的程序目录,然后修改日志中的所有的Aug为wr,并把修改后的文件保存到wr.txt

import shutil
shutil.copyfile('C:\\1.log', 'D:\\Python\\web\\1.txt')          # 复制文件到程序目录下
file = open('1.txt', 'r')
file_new = open('wr.txt', 'w')
for line in file:                                               # 按行读取文件内容
    if "Aug" in line:                                           # 查找我们所需要修改的内容
        line = line.replace("Aug", "wr")                        #替换Aug为wr
    file_new.write(line)                                        #修改后的内容写入新文件里
file.close()
file_new.close()

或者

import shutil
shutil.copyfile('C:\\1.log', 'D:\\Python\\web\\1.txt')
with open('1.txt', 'r') as file:
    with open('wr.txt', 'w') as new_file:
        for line in file:
            if "Aug" in line:
                line = line.replace("Aug", "wr")
                new_file.write(line)

python知识整合(模块)

发表于 2019-09-12 | 分类于 python

1、自定义模块

在Python中一个.py文件就是一个模块。

在python中自定义模块有2个作用。一个是规范代码,让代码更易于阅读。另一个是方便其他程序使用已经编写好的代码,提高开发效率、

要实现自定义模块主要分为创建模块和导入模块2部分。

1.1、创建模块

就是将模块中的相关代码编写在单独的文件中,文件名为模块名.py
要注意的是设置的模块名不能与python自带的标准库名称一样。如果一样的话。先导入了我们自定义的模块后,就不能再导入python自带的标准库

1.2、使用import语句导入模块

使用import导入
语法格式

import modulename [as alias]

部分参数说明:
[as alias] 给模块起的别名,可以通过该别名使用模块

在调用模块中的变量、函数或者类等时,需要在变量、函数或者类名前面添加“模块名.”

使用import语句也可以一次导入多个模块
如

import re,requests,os

1.3、使用from…import语句导入模块
在使用import语句导入模块时,每执行一条import语句就会创建一个新的命名空间,且在调用模块中的变量、函数或者类时,需要在变量、函数或者类名前面添加“模块名.”。

使用from…import语句导入模块是把具体的定义导入到当前的命名空间,不需要添加前缀,直接通过具体的变量、函数或者类等访问即可。

语法格式:

from modelname import member

参数说明:
modelname:模块名区分大小写
member:用于指定要导入的变量、函数或者类等,可以同时导入多个定义,如果要想导入全部定义使用“*”代替。

注意:在导入模块时,如果使用了通配符*导入全部定义之后,可以使用dir()来查看具体导入了哪些定义。

1.3、模块搜索的目录

当使用import语句导入模块时,在默认的情况下,按一下顺序进行查找
1、在当前目录进行查找
2、在python环境变量下的每个目录查找
3、到python的默认安装目录下查找

说明的各个目录的具体位置都是保存在标准模块sys的sys.path变量中。可以通过一下代码输出具体的目录

import sys
print(sys.path)

如果要导入的模块不在标准模块sys的sys.path变量中,会报错。(注意模块名区分大小写)

这时有3种方式可以将指定的目录添加到sys.path中

1、临时添加
通过该方法添加的目录只在执行当前文件的窗口有效,窗口关闭后就失效。
语法格式

import sys
sys.path.append("要添加的指定目录")

2、增加.pth文件(推荐)

在python安装目录的子目录Lib\site-packages子目录中,创建一个扩展名为.pth的文件,文件名任意,在该文件中添加要导入模块所在的目录。然后重新打开要执行导入模块的python文件,使得新添加的目录生效。

通过该方法添加的目录只在当前版本的python中有效

3、在PYTHONPATH环境变量中添加
在系统的环境变量对话框中,查找在PYTHONPATH环境变量,如果没有就创一个,然后添加所要导入的模块的目录。然后重新打开要执行导入模块的python文件,使得新添加的目录生效。

通过该方法添加的目录在不同版本的python中都有效

2、以主程序的形式执行

创建一个aaa模块

p = "苹果"
def fun_c():
    p = "一个烂苹果"
    print(p)
if __name__=="__main__":
    print("哈哈哈哈")

在text中导入该模块

import aaa
print(aaa.p)

输出

苹果

说明:如果在aaa模块中没有if语句的话,会把下面的测试语句( print(“哈哈哈哈”))也一块执行。但是我们只想要输出变量p。故将测试语句放入if语句。

3、python中的包

python中的包是一个分层的目录结构,它将一组功能相近的模块组织在一个目录下,这样就可以起到代码规范的作用,又可以避免模块重名引起的冲突

简单来说python的包就是一个含义init.py的文件的文件夹

3.1、创建

1、创建包就是创建一个文件夹,并在文件里创建一个名称为init.py的文件。在init.py文件里可以不编写代码,也可以编写代码,在导入包时会自动执行。

注意:init.py文件是一个模块文件,模块名为包名。在a包中创建的init.py文件,对应的模块名为a

3.2、使用包

创建包,然后在包中创建相应的模块,然后再使用import语句从包中加载模块。
从包中加载模块有以下3种方式。

1、通过”import+完整包名+模块名”的方式加载指定模块
语法格式

import 完整包名.模块名

通过该方式,访问模块中的变量时,语法格式如下

完整包名.模块名.变量名

2、通过”from+完整包名+import+模块名”的方式加载指定模块
语法格式:

from 完整包名 import 模块名

通过该方式,访问模块中的变量时,语法格式如下

模块名.变量名

3、通过通过”from+完整包名+import+模块名+定义名”的方式加载指定模块
语法格式

from 完整包名.模块名  import 定义名1,定义名2,....

定义名可以是函数、类、变量名等

通过该方式,访问模块中的函数、类、变量等,语法格式如下

定义名

如果使用*号则表示加载该模块下的所有定义

4、引用其他模块

在python中除了自定义模块,还有其他模块,主要包括标准模块和第三方模块。

下表为python中常用的内置的标准模块
| 模块名 | 概述 |
| ——– | ———————————————————— |
| sys | 与python解释器及其环境操作相关的标准库 |
| time | 提供与时间相关的各种函数的标准库 |
| os | 提供了访问操作系统服务功能的标准库 |
| calendar | 提供了与日期相关的各种函数的标准库 |
| urllib | 用于读取来自网上(服务器上)的数据的标准库 |
| json | 用于使用JSON序列化和反序列化 |
| re | 用于在字符串中执行正则表达式匹配和替换 |
| math | 提供标准算术运算函数的标准库 |
| decimal | 用于进行精确控制运算精度、有效位数和四舍五入操作的十进制运算 |
| shutil | 用于进行高级文件操作,如复制等 |
| logging | 提高了灵活的记录事件、错误、警告和调试信息等日志信息的功能 |
| thinker | 使用python进行GUI编程的标准库 |
当然python有许多标准库,可以在python的安装目录下,的DOC目录下的扩展名为.chm文件(就是python的帮助文档)打开文件,文件里的The Python Standard Library下面的Python Runtime Services里进行查看,当然也可以上网查找。

5、牛刀小试

5.1、输出6位数的验证码

要求确保6位数中有一位大写字母,一位小写字母,一位数字

import random, string
code_li = []
"""确保6位数中有一位大写字母,一位小写字母,一位数字"""
code_li.append(random.choice(string.ascii_lowercase))    # 随机添加小写字母
code_li.append(random.choice(string.digits))             # 随机添加
code_li.append(random.choice(string.ascii_uppercase))    # 随机添加大写字母
while len(code_li)<6:
    code_li.append(random.choice(string.ascii_lowercase+string.digits+string.ascii_uppercase))
    print(code_li)
q_code = "".join(code_li)
"""
join()函数
语法:  'sep'.join(seq)
参数说明
sep:分隔符。可以为空
seq:要连接的元素序列、字符串、元组、字典
上面的语法即:以sep作为分隔符,将seq所有的元素合并成一个新的字符串
返回值:返回一个以分隔符sep连接各个元素后生成的字符串
"""
print(q_code)

5.2、转化为时间戳

把2019-01-02 20:12:54转化为时间戳

import time
dt = "2019-01-02 20:12:54"
timeArray = time.strptime(dt,"%Y-%m-%d %H:%M:%S")  # 根据指定的格式把一个时间字符串解析为时间元组。(转化为时间戳)
# timestamp = time.mktime(timeArray)   # 返回用秒数来表示时间的浮点数
# print(timestamp)
print(timeArray)

python知识整合(面向对象程序设计)

发表于 2019-09-12 | 分类于 python

1、面向对象概述

1.1、对象(object)

对象是一个抽象的概念,表示任意存在的事物

对象可以分为2部分,就是静态部分和动态部分。静态部分被称为“属性”,如人的性别;动态部分指的是对象的行为(对象执行的动作),如人可以走路

在python中,一切都是对象,即不仅把具体事物称为对象,字符串、函数等也是对象。(pyhton天生就是面向对象的)

1.2、类

类是封装对象的属性和行为的载体,反过来说具有相同属性和行为的一类实体被称为类。
如定义一个鸟类,在该类中可以定义每个对象共有的属性和方法。而每一只鸟就是一个对象。
对象是类的实例

1.3、面向对象程序设计特点

面向对象程序设计具有3大基本特征:封装,继承,多态。

1、封装

封装是面向对象编程的核心思想,将对象的属性和行为封装起来,载体是类。类通常会对客户隐藏其实现细节。如我们看一本书,只需要看书的内容就可以,而不需要知道书是这么制作的。

封装思想保证了类内部数据结构的完整性,提高了程序的可维护性。

2、继承
矩形是四边形的一种,矩形拥有四边形的全部特点,反之不然。
矩形类可以看为继承四边形类后产生的类,称为子类。而四边形类称为父类或者超类。
在python中子类的实例都是父类的实例,但是不能说父类的实例都是子类的实例。
继承是重复利用的重要手段,子类可以继承父类的属性的同时,又增加了子类特有的属性和行为。

3、多态
将父类对象应用于子类的特征就是多态。
就是子类继承父类特征的同时,也具备了自己的特征,并且能够实现不同的效果,这就是多态化结构。

2、类的定义和使用

2.1、定义类

使用class关键字来定义类
语法格式

class ClassName:
    '''类的帮助信息'''        # 类文档字符串
    statement               # 类体 ,如果没有想好类的功能,可以使用pass代替

2.2、创建类的实例对象

创建类的实例的语法:

ClassName(parameterlist)

注意在python中创建实例不使用new关键字,这是它与其他面向对象语言的区别。

2.3、创建 int ()方法

int ()方法是一个特殊的方法,每当创建一个类的新实例时,Python会自动执行它。

int ()方法必须包含一个self参数,且必须是第一个参数。self参数是一个指向实例本身的引用,用于访问类中的属性和方法。在方法调用时会自动传递实际参数self

如

class Apple:
    """苹果类"""
    def __init__(self):
        print("这是苹果类")

​
wildApple = Apple()

可以看出,在创建苹果类的实例时,虽然没有为 int ()方法指定参数,但是该方法会自动执行

当然 int ()方法出了self参数外,还可以自定义一些参数。
例子

class Apple:
    """苹果类"""
    def __init__(self, size, color):      # 构造方法
        print("这是苹果")
        print(size)
        print(color)

​
size_1 = “个大”
color_1 = “又红”
wildApple = Apple(size_1, color_1) # 创建苹果类的实例

2.4、创建类的成员并访问

类的成员主要由实例的方法和数据成员组成。创建了类的成员后,可以通过类的实例进行访问

1、创建实例方法并访问

实例方法其实就是在类中定义函数

与int()方法类似
语法格式如下

def  functionName(self,parameterlist):
    block

参数说明:
functionName:用于指定方法名,一般小写字母开头

self : 必要参数,其名称要是self以外的单词,用self只是个习惯

parameterlist: 用于指定除self以外的参数

block: 方法体,实现具体功能

实例方法创建完成之后,可以通过类的实例名称名称和“.”来访问。
语法格式

instanceName.functionName(parametervalue)

2、创建数据成员并访问
数据成员是指类中定义的变量(属性),根据定义的位置可以分为类属性和实例属性。

类属性:定义在类中且在函数体外的属性。可以在使用实例化的对象中公用。

实例属性定义在类的方法(实例方法)中的属性,只作用于当前的实例。
如

class Apple:
    """苹果类"""
    size = "个大"             # 定义类属性
    color = "又红"            # 定义类属性

    def __init__(self):       # 构造方法
        self.weight = "又重"
        print("这是苹果")
        print(Apple.size)
        print(Apple.color)
        print(self.weight)     # 定义实例属性

​
apple = Apple() # 创建苹果类的实例

注意实例属性只能通过实例名访问。当然实例属性也可以通过实例名称修改,修改后不影响该类的其他的实例中相应的实例属性的值
如

class Apple:
    """苹果类"""

    def __init__(self):       # 构造方法
        self.weight = "又重"
        print(self.weight)     # 定义实例属性

​
apple1 = Apple()
apple2 = Apple()
apple1.weight = “太轻了”
print(apple1.weight)
print(apple2.weight)

2.5、访问限制

访问限制有3种方式。可以在属性或者方法前加个单下划线,双下划线,或者首尾加双下划线

1、首尾加双下划线:表示定义的特殊方法,一般是系统定义的名字如int()

2、单下划线:表示保护(protected)类型的成员,只允许类本身或者子类访问,但不可以使用“from module import*”语句导入

如:

class Apple:
    """苹果类"""
    _weight_apple = "又重"   # 定义保护属性

    def __init__(self):       # 实例方法
        print(Apple._weight_apple)     # 在实例方法中访问保护属性

​
apple1 = Apple()
print(apple1._weight_apple)

保护属性可以通过实例名进行访问

3、双下划线:表示私有(private)类型成员,只允许定义该方法的类的本身进行访问,而且不能通过类的实例进行访问。但是可以通过”类的实例名._类名__xxx”进行访问

如

class Apple:
    """苹果类"""
    __weight_apple = "又重"   # 定义私有属性

    def __init__(self):       # 实例方法
        print(Apple.__weight_apple)     # 在实例方法中访问私有属性

​
apple1 = Apple()
print(apple1._Apple__weight_apple)

3、属性(property)

3.1、创建用于计算的属性

可以通过@property(装饰器)把一个方法转化为属性,从而实现用于计算的属性。可以直接通过方法名来访问。
语法格式

@property
def methodname(self)
    block

如

class Rect:
    def __init__(self, width, height):
        self.width = width           # 矩形的宽
        self.height = height         # 矩形的高

    @property                        # 将方法转化为属性
    def area(self):
        return self.width*self.height    # 返回矩形的面积

​
rect = Rect(5, 4) # 创建类的实例
print(rect.area) # 输出属性的值

3.2、为属性添加安全的保护机制

如果想要创建一个可读不能修改的属性,那么可以使用@property(装饰器)实现该效果

例子:

class Rect:
    def __init__(self, width):
        self.width = width           # 矩形的宽

    @property                        # 将方法转化为属性
    def area(self):
        return self.width

​
rect = Rect(5) # 创建类的实例
print(rect.area) # 输出属性的值
rect.area = 6 # 修改属性值
print(rect.area) # 获取属性值,会抛出AttributeError

4、继承

4.1、继承的基本语法:

语法格式:

class ClassName(baseclasslist):
    """类的帮助信息"""                   # 类文档字符串
    statement                          # 类体

部分参数说明:
baseclasslist:用于指定要继承的基类(父类),可以多个。类名之间用逗号隔开。如果不指定,将使用所以python对象的根类object.

4.2、方法重写

基类(父类)的成员都会被派生类(子类)继承,当基类中的某个方法不完全适用于派生类时,就需要在派生类中重写基类的这个方法。
例子:重写基类中的harvest方法

class Fruit:
    def __init__(self, color = "绿色"):
        Fruit.color = color             # 定义类的属性

    def harvest(self):
        print("水果……")

​
class Orange(Fruit):
color = “橙色”

def __init__(self):
    print("\n我是橘子")
    super().__init__()                   # 调用基类的__init__()方法

def harvest(self, color):
    print("橘子是:" + color + "的")      # 输出参数形式color
    print("橘子已经收获了")
    print("橘子原来是:" + Fruit.color + "的")   #输出类属性color

​
orange = Orange()
orange.harvest(“橙色”)

这边有一点要注意,在派生类中定义init()方法时,不会自动调用基类的init()方法。故需要对派生类的init()方法进行初始化,就是在派生类中只有super()函数进行调用基类的init()方法,如下代码

1
super().__init__()

python知识整合(函数)

发表于 2019-09-12 | 分类于 python

1、函数的创建与调用

函数出了python中的内置函数外,我们也也可以根据需求,自己创建函数
创建函数语法格式

def functionname([parameterlist])
    ['''comments''']
    [functionbody]

调用函数语法格式

functionname([parameterlist])

小技巧:
在调用函数时,如果指定了“comment(注释)”参数,那么在调用函数时,输入函数名及其左侧小括号时,就会显示该函数的帮助信息(注释的内容)

例子:

def filterchar(string):
    '''
    功能:过滤危险字符,并将过滤后的结果输出
    about:要过滤的字符串
    没有返回值
    '''
    import re
    pattern = r'(黑客)|(抓包)|(监听)|(trojan)'
    sub = re.sub(pattern, "@_@", string)
    print(sub)
filterchar("黑客")

2、参数传递

2.1、形式参数与实际参数(形参与实参)

形式参数(形参):在定义函数时,函数名后括号内的参数为形参
实际参数(实参):在调用一个函数时,函数名后括号内的参数为实参,也就是调用函数时,我们给函数传入的参数。

根据实践参数类型的不同,可以分为值传递和应用传递。当实际参数为不可变对象时,就是值传递:当实际参数为可变对象时就是引用传递。

例子:
定义函数
def demo(obj):
print(“元值:”, obj)
obj += obj
调用函数

print("========值传递========")
mot = "唯有在被追赶的时候,你才能真正的奔跑。"
print("函数调用前:", mot)
demo(mot)   # 采用不可变量字符串
print("函数调用后:", mot)
print("========引用传递========")
list1 = ['apple', 'banana', 'orange', 'pear']
print("函数调用前:", list1)
demo(list1)   # 采用可对象列表
print("函数调用后:", list1)

输出

========值传递========
函数调用前: 唯有在被追赶的时候,你才能真正的奔跑。
元值: 唯有在被追赶的时候,你才能真正的奔跑。
函数调用后: 唯有在被追赶的时候,你才能真正的奔跑。
========引用传递========
函数调用前: ['apple', 'banana', 'orange', 'pear']
元值: ['apple', 'banana', 'orange', 'pear']
函数调用后: ['apple', 'banana', 'orange', 'pear', 'apple', 'banana', 'orange', 'pear']

可以看出,值传递改变形参的值,但是不改变实参的值。
引用传递改变形参的值,同时也改变实参的值。

2.2、位置参数

位置参数也称必备参数,必须按照正确的顺序传入函数中

1、数量必须与定义时的一样

在调用函数时,指定的实际参数的数量必须与形式参数一样一样,否则会抛出TypeError异常,提示缺少的位置参数

2、位置必须与定义时的一致

不一致会产生下面2种异常
(1)、抛出TypeErro异常
该种异常主要是实参与形参类型不一致,且在函数中,2种类型无法转换
(2)、产生的结果与预期的不符
就是位置错了,但是他们的类型一致,比如身高和体重的参数位置反了。
这其实是一种bug

2.3、关键字参数

关键字参数是指使用形参的名字来确定输入的参数值,使用该方法,实参的位置不需要一致。
如调用fun_bmi(persion,height,weight)函数,可以通过关键字参数

fun_mbi(height = 1.58, persion = 'john', weight = '50')

2.4、为参数设置默认值

语法格式:

def functionname(…,[parameter1 = defaultvaluel]):
    [functionbody]

查看函数的默认值参数的语法

函数名.__defaults__

使用可以变量作为参数的默认值时,多次调用,可能会产生意料之外的结果。
为了防止这种情况的产生,我们可以使用None作为可变对象的默认值,还要加上检验代码。

在定义函数时,为形式参数设置默认值时,默认参数必须指向不可变对象

2.5、可变参数

可变参数也称不定长参数。即传入函数的参数可以是0个,1个,2个等等。
主要有*parameter和**parameter 2种形式

1、*parameter
这种形式表示接收任意多个实际参数并将其放入一个元组中。
如

def printfruit(*fruitname):
    print('\n我喜欢的水果有:')
    for i in fruitname:
        print(i)   # 输出水果名称

printfruit('apple')
printfruit('apple', 'banana', 'pear')

输出

我喜欢的水果有:
apple

我喜欢的水果有:
apple
banana
pear

如果想要用一个已经存在的列表作为函数的可变参数,可以在列表名称前加个’*‘。
如

a = ['apple', 'banana', 'pear']
printfruit(*a)

2、**parameter
这种形式表示可以接收任意多个类似关键字一样的显示赋值的实际参数
如

def printsign(**sign):
    print()
    for key, value in sign.items():    # 遍历字典
        print(key + "的星座是:" + value)
printsign(a='水瓶')
printsign(a='水瓶', b='狮子')

输出

a的星座是:水瓶

a的星座是:水瓶
b的星座是:狮子

如果想要用一个已经存在的字典作为函数的可变参数,可以在字典名称前加个’**‘。

3、返回值

在python中无论return语句在什么位置,只有得到执行,就会直接结束函数的执行
语法格式:

result =return [value]

说明
value为一个可选参数,用于指定要返回的值(可以是一个值,也可以是多个值,值可以是任意类型)

当函数中没有return语句,,或者省略return语句的参数时,将返回None(空值)

4、变量的作用域

4.1、局部变量

局部变量就是在函数内部定义并使用的变量。(在函数外部使用会抛出NameError异常)

4.2、全部变量

1、在函数外部定义
值得注意的事,当全局变量与局部变量重名时,对函数体内的变量进行赋值后,不影响函数体外的变量。

2、在函数内定义
在函数体内定义全局变量,需要使用global关键字
语法格式

global 变量

5、匿名函数

匿名函数就是没有名字的函数,一般只使用一次。使用lambda关键字
语法格式

result = lambda [arg1 [,arg2,...,argn]]:expression

参数说明:
result:用于调用lambda表达式
[arg1 [,arg2,…,argn]]:可选参数,用于指定的要传递的参数列表
expression: 必选参数,用于指定一个实现具体功能的表达式。

注意:使用lambda关键字只能有一个返回值和出现其他非表达式语句(如for或while)
如:

import math
r = 10
result = lambda r: math.pi*r*r
print("半径为", r, "的圆的面积为", result(r))

lambda的首页用途是指定短小的回调函数。

6、牛刀小试

6.1、输出第几天

请编写一个程序,实现输入任意的年月日就可以计算出是这一年的第几天,如输入20190203,就可以输出这是2019年的第34天。

def data(y, m, d):
    if m <= 2:
        return "这是"+str(y)+"年的第"+str((m-1)*31+d)+"天"
    elif m in (3, 5, 7, 9, 10, 11, 12):
        return "这是" + str(y) + "年的第" + str((m - 1) * 31 + d - m//2 - 1 + y % 4 - 1) + "天"
    elif m in (4, 6, 8):
        return "这是" + str(y) + "年的第" + str((m - 1) * 31 + d - m//2 - 1 + y % 4) + "天"

​
if name == ‘main‘:
a = data(2017, 1, 1)
print(a)

6.2、找出重复IP

下面list 中提供了几组IP地址,编写一个函数,将list中重复出现的IP地址找出来。
list=[‘192.168.1.1’,’10.192.66.72’,’10.199.88.132’, ‘192.168.1.1’,’1.192.168.163’]

def main():
    a=['192.168.1.1','10.192.66.72','10.199.88.132', '192.168.1.1','192.168.163']
    b=[]
    c=[]
    for i in range (0,len(a)):
        if a[i] not in b:
            b.append(a[i])
        else:
            c.append(a[i])

    print (c)
if __name__ == '__main__':
    main()

6.3、大写模式

编写-一个函数,把输入的字母统一成大写模式, 如输入“go big or go home”,输出为“60BIG OR G0 HOME”。

1
2
3
4
5
6
def demo(a):
a = a.upper()
return a
if __name__ == '__main__':
b = demo('go big or go home')
print(b)

Python知识集合(异常处理和程序调试)

发表于 2019-09-12 | 分类于 python

1、异常处理语句

1.1、try…except语句

语法格式:

try:
    block1
except [ExceptionName [as alias]]:
    block2

参数说明:
block1:表示可能出错的代码块

ExceptionName [as alias]:可选参数,用于指定要捕获的异常,其中 ExceptionName表示要捕获的异常名称,如果在其右侧加上 as alias 表示当前的异常指定一个别名。

block2:表示进行异常处理的代码块,在这里可以输出固定的提示信息,也可以通过别名输出异常的具体内容

注意:如果except后面不知道异常名称,则表示捕获全部异常。使用try…except语句捕获异常后,程序会继续执行。

1.2、try …except…else语句

try …except…else语句与try …except语句的不同在于当没有异常时,使用else子语句。

例子

def division():
    ''' 实现功能:分苹果 '''
    print("\n-----------------分苹果了-----------------\n")
    apple = int(input("请输入苹果个数:"))
    children = int(input("请输出一共有几个小朋友:"))
    result = apple // children                 # 计算每个小朋友分几个苹果,输出整数
    remain = apple - result * children         # 计算剩下的苹果
    if remain > 0:
        print(apple, "个苹果,平均分给", children, "个小朋友,每人分", result,"个,剩下", remain, "个。")
    else:
        print(apple, "个苹果,平均分给", children, "个小朋友,每人分", result, "个。")
if __name__ == '__main__':
    try:                                                # 捕获异常
        division()
    except ZeroDivisionError:                            # 处理zero异常
        print("\n出错了,不能把苹果分给0个小朋友。")
    except ValueError as e:                              # 处理value异常
        print("输入错误:", e)
    else:                                                # 没有抛出异常时执行
        print("苹果成功分给小朋友。")

1.3、try …except …finally语句

不管是否有异常产生,都会执行finally里的语句
语法格式:

try:
    block1
except [ExceptionName [as alias]]:
    block2
finally:
    block3

例子

def division():
    ''' 实现功能:分苹果 '''
    print("\n-----------------分苹果了-----------------\n")
    apple = int(input("请输入苹果个数:"))
    children = int(input("请输出一共有几个小朋友:"))
    result = apple // children                 # 计算每个小朋友分几个苹果,输出整数
    remain = apple - result * children         # 计算剩下的苹果
    if remain > 0:
        print(apple, "个苹果,平均分给", children, "个小朋友,每人分", result,"个,剩下", remain, "个。")
    else:
        print(apple, "个苹果,平均分给", children, "个小朋友,每人分", result, "个。")
if __name__ == '__main__':
    try:                                                # 捕获异常
        division()
    except ZeroDivisionError:                            # 处理zero异常
        print("\n出错了,不能把苹果分给0个小朋友。")
    except ValueError as e:                              # 处理value异常
        print("输入错误:", e)
    else:                                                # 没有抛出异常时执行
        print("苹果成功分给小朋友。")
     finally:
         print("进行了一次分苹果操作")

输出:

-----------------分苹果了-----------------

请输入苹果个数:8
请输出一共有几个小朋友:0

出错了,不能把苹果分给0个小朋友。
进行了一次分苹果操作

1.4、使用raise语句抛出异常

如果函数或方法中有异常,却不想在当前函数或方法中处理异常,可以使用raise处理异常。
语法格式:

raise [ExceptionName [(raise)]]

2、使用assert语句调试程序

语法格式:

assert expression [,reason]

说明:
expression: 条件表达式,如果该表达式为真什么,都不用做,如果为假抛出AssertionError异常。
reason:可选参数,用于对判断条件进行描述,为了以后更好的知道哪里出了问题
例子

def division():
    ''' 实现功能:分苹果 '''
    print("\n-----------------分苹果了-----------------\n")
    apple = int(input("请输入苹果个数:"))
    children = int(input("请输出一共有几个小朋友:"))
    assert apple > children, "苹果不够分"
    result = apple // children                 # 计算每个小朋友分几个苹果,输出整数
    remain = apple - result * children         # 计算剩下的苹果
    if remain > 0:
        print(apple, "个苹果,平均分给", children, "个小朋友,每人分", result,"个,剩下", remain, "个。")
    else:
        print(apple, "个苹果,平均分给", children, "个小朋友,每人分", result, "个。")
if __name__ == '__main__':
    division()

输出:

请输入苹果个数:5
请输出一共有几个小朋友:8
Traceback (most recent call last):
  File "D:/Python/web/test.py", line 14, in <module>
    division()
  File "D:/Python/web/test.py", line 6, in division
    assert apple > children, "苹果不够分"
AssertionError: 苹果不够分

通常情况下,assert语句可以和异常处理语句结合使用,把上面的代码的最后一行语句改为

try:
    division()
except AssertionError as e:
    print("\n输出有误:", e)

输出

-----------------分苹果了-----------------

请输入苹果个数:5
请输出一共有几个小朋友:8

输出有误: 苹果不够分

注意:assert语句只在调试阶段有效。我们可以通过在执行python命令时加入-O(大写)参数来关闭asset语句。
如在命令行窗口下可以使用以下命令

1
python -O 调试文件.py

Python知识整合(字符串及正则表达式)

发表于 2019-09-12 | 分类于 python

1、字符串常规操作

1.1、拼接字符串

使用“+”号可以实现多个字符串的拼接,并产生一个字符串对象。
如

a = "123"
print(a+"1234")

1.2计算字符串长度

使用len()函数
如

str ="123a,时候"
print(len(str))

输出

7

可以看出在len函数计算字符串的长度时,不区分数字,英文,汉字,所有字符都认为是一个字节
但是,如果采用UTF-8编码,汉字占3个字节,采用GBK或者GB2312编码时,汉字占2个字节
如

str ="123a,时候"
print(len(str.encode()))   #utf-8编码
  print(len(str.encode(gbk)))   #gbk编码 

输出

15
12

1.3、截取字符串

通过切片方法实现
语法格式如下

string(start : end : step)

如

str = "你就是个啊哈"
 str1 = str[1]       #截取第二个字符
 str1 = str[2:]      #从第3个字符开始截取
 str2 = str[:2]      #从左边开始截取2个字符
 str3 = str[2:4]   #截取第3个到第4个字符

1.4、分隔字符串

使用split函数分隔
语法格式

str.split(sep,maxsplit)

说明
1、str:表示进行分隔的字符串
2、sep表示指定的分隔符,可以包含多个指定字符,如果不指定,那么默认为None,即所有的空字符(包括空格,\n等等)
3、maxsplit:可选参数,用于指定分隔的次数,如果不指定或者为-1,分隔次数没有限制,否则返回的元素最多为maxsplit+1。
4、如果不指定sep,也不能指定maxsplit
5、返回值为字符串列表

1.5、检索字符串

1、count方法
count()方法检索字符串在另一个字符串中出现的次数。如果字符串不存在返回0,否则返回次数,其语法格式如下。

str.count(sub[,start[,end]])

说明:
str表示原字符串
sub表示要检索的字符串
start表示可选参数,检索的起始位置,若不指定,从头检索
end,与start相似。

2、find方法
检索是否包含指定的字符串,如果检索的字符串不存在则,返回-1,否则返回该字符串首次出现的索引
语法格式

str.find(sub[,start[,end]])

3、index()方法
与find()方法类似,不过使用index()方法,当指定的字符串不存在时抛出异常
语法格式

str.index(sub[,start[,end]])

4、startwith()方法
检测是否以指定字符串开头,是返回True,不是返回False
语法格式:

str.startswith(prefix[,start[,end]])

参数说明,str表示原字符串,prefix表示要检索的字符串
其他参数说明与find()方法类似

5、endwith()方法
检测是否以指定字符串结尾,是返回True,不是返回False
语法格式

str.endswith(suffix[,start[,end]])

1.6、字母的大小写转换

1、lower()方法
将字符串中的全部的大写字母转化为小写字母。
语法格式:

str.lower()

2、upper()方法
将字符串中的全部的小写字母转化为大写字母。
语法格式:

str.upper()

3、swapcase()方法
同时将字符串中的全部的小写字母转化为大写字母,全部的大写字母转化为小写字母。

str.swapcase()

1.7、去除字符串中的空格和特殊字符

特殊字符在这里指的是:\t \r \n(制表、回车、换行)
1、strip()方法
去除字符串的左右两侧的空格和特殊字符
语法格式

str.strip([chars])

如

str1 = " 12323 \n"
print("原字符串str1:" + str1)
print("字符串:" + str1.strip() + ".")   # 去除首尾的空格和特殊字符
str2 = "#133#."
print("原字符串str2:" + str2)
print("字符串:" + str2.strip('#.'))         #去除首位的#或者.

输出

原字符串str1: 12323 

字符串:12323.
原字符串str2:#133#.
字符串:133

2、lstrip()方法
lstrip()方法可以去除字符串左侧的空格和特殊字符,
语法格式

str.lstrip([chars])

3、rstrip()方法
rstrip()方法可以去除字符串由右侧的空格和特殊字符,
语法格式

str.rstrip([chars])

1.8、格式化字符串

格式化字符串就是先定义一个模板,然后在模板中留几个空位,空位用占位符来标记

1、使用%号操作符(逐渐没落)

常用的格式化字符
| 格式化字符 | 说明 | 格式化字符 | 说明 |
| ———- | ——————— | ———- | ———————- |
| %s | 字符串(采用str显示) | %r | 字符串(采用repr显示) |
| %c | 单个字符 | %o | 八进制整数 |
| %d或者%i | 十进制整数 | %e | 指数(基地写为e) |
| %x | 16进制整数 | %E | 指数(基地写为E) |
| %f或者%F | 浮点数 | %% | 字符% |

如

a = "小明为莆田%d中学生,学号为%d,同学都叫他%s"   # 定义模板
b1 = (6, 31111111, '小明')                   # 定义与转化的内容
print(a % b1)                               # 格式化输出

输出

小明为莆田6中学生,学号为31111111,同学都叫他小明

2、使用字符串对象的format()方法(推荐使用)
语法格式

str.format(args)

args用于指定与转化的项

format()方法中常用的格式化字符
| s | 对字符串类型进行格式化 |
| ——– | ——————————————- |
| b | 将十进制数自动转换成二进制数表示再格式化 |
| d | 十进制整数 |
| o | 将十进制数自动转换成八进制数表示再格式化 |
| c | 将十进制数自动转换成对应的unicode字符 |
| x 或者 X | 将十进制数自动转换成十六进制数表示再格式化 |
| e或者E | 转化为科学计数法表示再格式化 |
| f或者F | 转化为浮点数(默认小数点后保留6位)再格式化 |
| g或者G | 自动在e和f或者E和F中切换 |
| % | 显示百分比(默认小数点后保留6位) |

如

a = "小明为莆田{:d}中学生,学号为{:0>7d},同学都叫他{:s}"   # 定义模板
b1 = a.format(6, 31111111, '小明')             # 定义与转化的内容
print(b1)            # 格式化输出

输出

小明为莆田6中学生,学号为31111111,同学都叫他小明

2、正则表达式基础

2.1、行定位符

行定位符就是用来描述字符串的边界。“^”表示行的开始,“$”表示行的结尾
如

^tm$

2.2、常用的元字符

代码 说明
. 匹配除换行符以外的任意字符
\w 匹配字母数字、下划线或者汉字
\s 匹配任意的空格符
\d 匹配数字
\b 匹配单词的开始或者结束
^ 匹配字符串的开始
$ 匹配字符串的结尾

2.3、限定符

如匹配8位QQ号码可以使用下面的方式表示

^\d{8}$

常用的限定符
| 限定符 | 说明 | 举例 |
| —— | ——————————- | ——————————————— |
| ? | 匹配前面的字符零次或者一次 | app?le,该表达式可以匹配apple或者aple |
| + | 匹配前面的字符者一次或多次 | app+le,该表达式可以匹配apple到app….le |
| | 匹配前面的字符者零次或多次 | apple,该表达式可以匹配aple到app….le |
| {n} | 匹配前面的字符者n次 | app{2}le,该表达式可以匹配appple |
| {n,} | 匹配前面的字符者最少n次 | app{2,}le,该表达式可以匹配appple到appp…le |
| {n,m} | 匹配前面的字符者最少n次,最多m次 | app{2,3}le,该表达式可以匹配appple或者apppple |

2.4、字符类

如果匹配没有预定义的元字符的字符集合(比如元音字母a,e,i,o,u)我们可以使用方括号,然后把要匹配的内容写在方括号里,如[aeiou]匹配任何一个元音字母。
[0-9]与\d的效果一样
[a-z0-9A-Z]与\w的效果一样(只考虑英文)
[\u4e00-\u9fa5]匹配给定字符串的任意一个汉字,匹配连续多个汉字[\u4e00-\u9fa5]+

2.5、排除字符

把^放在方括号里就是排除的意思
如

[^a-zA-Z]

该表达式用于匹配一个不是字母的字符串

2.6、选择字符

例子,匹配身份证号码
身份证号码为15位或者18位,如果是15位的全为数字,如果是17位,则最后一位是效验位,为数字或者X(x)
可以使用下面表达式匹配

^\d{15})|(^\d{18}) |(^\d{17} (\d|X|x)$

意思是匹配15位或者18位数字或者17位数字和最后一位是数字或者X或者x

2.7、转义字符

正则表达式中的转义字符也是将特殊字符(“.”、“?”,“\”)变为普通的字符
。如用正则表达式表示127.0.0.1这样格式的IP地址

[1-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}

注意括号在正则表达式也算一个字符

2.8、分组

例子

(thir|four)th

意思是匹配单词thirth或者fourth,如果不使用小括号,就变成了匹配单词thir和fourth

小括号的第二个作用就是分组。
如

(\.[1-9]{1,3}){2},就是对(\.[1-9]{1,3})进行操作

2.9、在python中使用正则表达式语法

在Python中使用正则表达式就是将其作为模式字符串使用的。
将匹配以m开头的正则表达式转化为模式字符串

'\\bm\\w*\\b'

因为模式字符串可能包含大量的特殊字符和斜杠,所以需要使用原生字符串
就是在模式字符串前加上r或者R.
如
r ‘\bm\w*\b’

3、使用re模块实现正则表达式操作

3.1、匹配字符串

1.使用match()方法进行匹配
如果在其实位置匹配成功,则返回Match对象,否则返回None,其语法格式如下:

re.match(pattern,string,[flags])

说明
pattern:表示模式字符串,由要匹配的正则表达式转换而来
string:表示要匹配的字符串
flags:可选参数,表示标识位,用于控制匹配方式,如是否区分字母大小写。
常用的标志如下表所示
| 标志 | 说明 |
| ————- | ———————————————————— |
| A或ASCII | 对\w、\W、\b、\B、\d、\D、\s、\S只进行ASCII匹配(只适用Python3.x) |
| I或ICNORECASE | 执行不按字母大小写匹配 |
| M或MULTLINE | 将^和$用于包括整个字符串的开始和结尾的每一行 |
| S或DOTALL | 使用“.”字符匹配所有字符,包括换行符 |
| X或VERBOSE | 忽略模式字符串中为转义的空格和注释 |

如

import re
pattern = r'mr_\w+'    # 模式字符串
string = 'MR_SHOP mr_shop'   # 要匹配的字符串
match = re.match(pattern, string,re.I)  # 匹配字符串不区分大小写
print("匹配值的起始位置:", match.start())
print("匹配值的结束位置:", match.end())
print("匹配位置的元组:", match.span())
print("要匹配的字符串:", match.string)
print("匹配数据", match.group())

输出

匹配值的起始位置: 0
匹配值的结束位置: 7
匹配位置的元组: (0, 7)
要匹配的字符串: MR_SHOP mr_shop
匹配数据 MR_SHOP

2、使用search()方法进行匹配
search()方法用于在整个字符串的搜索第一个匹配的值,如果在匹配成功返回match对象,否则返回None
语法格式

re.search(pattern,string,[flags])

参数说明参考match方法

3、使用findall()方法进行匹配
findall方法主要用于整个字符串中搜索所有符合正则表达式的字符串,并以列表的形式返回。如果匹配成功返回包含匹配结构的列表,否则返回空列表。
语法格式

re.findall(pattern,string,[flags])

参数说明参考match方法
如

import re
pattern = r'([1-9]{1,3}(\.[0-9]{1,3}){3})'
str1 = '127.0.0.1 192.168.122.2'
match = re.findall(pattern, str1)
for i in match:
    print(i[0])

输出

127.0.0.1
192.168.122.2

3.2、替换字符

使用sub()方法进行字符串替换
语法格式

re.sub(pattern, repl, string, count, flags)

说明
pattern:表示模式字符串
repl:表示替换的字符串
string:表示要被查找替换的原始字符串
count: 可选参数表示模式匹配后替换的最大次数,默认为0表示替换所有的匹配
flags: 可选参数,表示标志位,用于控制匹配方式,如区分大小写等,参考match()方法

例子

import re
pattern = r'1[34578]\d{9}'
string = '中奖号码为:84795643 联系电话为:13611111111'
result = re.sub(pattern, '1xxxxxxxxxx', string)
print(result)

输出

中奖号码为:84795643 联系电话为:1xxxxxxxxxx

3.3、使用正则表达式分隔字符串

split()方法进行分隔字符串,并以列表形式返回
语法格式

re.split(pattern, string, [maxsplit], [flags])

说明
pattern:表示模式字符串
string:表示要匹配的字符串
maxsplit: 可选参数,表示最大的拆分次数
flags: 可选参数,表示标志位,用于控制匹配方式,如区分大小写等,参考match()方法
例子

import re
pattern = r'[?|&]'
url = 'http://www.baidu.com?a=xxx&b=yyyy'
result = re.split(pattern, url)
print(result)

输出

['http://www.baidu.com', 'a=xxx', 'b=yyyy']

4、牛刀小试

4.1、按要求输出字符串

已知字符串word=”aS98hdkHFSWEas754”,.编写一- 个程序,分别实现如下功能:
●请将word字符串中的大写字母改为小写字母,小写字母改为大写字母,
●请将word字符串中的数字取出,并输出成一 一个新的字符串

普通版:

word = "aS98hdkHFSWEas754"
 a = ""
 b = ""
 for i in word:
     if  97 <= ord(i) <= 122:        #  小写字母变大写
         a = a + i.upper()              
     elif   65 <= ord(i) <= 90:      # 大写字母变小写
        a = a + i.lower()
     else:                                        
         a = a + i                   # 数字不变
         b = b + i                   # 数字取出,组成新的字符串
 word = a
 print(word)
 print(b)

升级版:

word = "aS98hdkHFSWEas754"
word = word.swapcase()   # word字符串中的大写字母改为小写字母,小写字母改为大写字母
b = ""
for i in word:
    if '0'<=i <='9':
        b = b + i      # 数字取出,组成一个新的字符串
print(word)
print(b)

4.2、输出生日信息

张三的身份证号码是“210011196809210451”.请提取张三的生日信息并输出。

前置知识,身份证的第七位到第14位是出生日期,11位到14位是生日

number = "210011196809210451"
birthday = '张三的生日为:{:s}月{:s}日'                   # 定义模块化字符串
print(birthday.format(number[10:12], number[12:14]))   # 使用format方法输出张三生日

4.3、不重复字母

已知字符串word=”ABDPISDNGDA”.请去除word字符串多次出现的字母,仅留最先出现的一个。例如aabc经过去除后,输出abc。

b =""
word="ABDPISDNGDA"

for i in word:

    if i not in b:
        b += i
print(b)

4.4、英文句子倒叙输出

将一句英文句于单词顺序留序输出,但是不改变单词结构。例如: 1 am a beautiful ginl,输出为girl beautiful a am I

a = input("请输入英文句子:")
b = a.split()                      # 将字符串按空格分开,生产一个列表
c = ""
for index, item in enumerate(b):   # 利用索引倒叙输出列表的值,并拼接为字符串
    c = c + b[-1 - index] + " "
print(c)

输出

请输入英文句子:You are a beautiful girl
girl beautiful a are You 

python知识整合(序列)

发表于 2019-09-12 | 分类于 python

1、序列

序列就是用于存放多个值的连续的空间,且具有顺序关系。
python中序列结构主要包括列表、元素、集合和字典。

1.1索引(indexing)

索引是从0开始计算
在python中索引也可以是负数,从右向左计数,最右边的数是的索引为-1(也就是最后一个数的下标可以是-1).
如

a = ["你","好","啊","吗"]
print( a[0] )
print(a[-4])
print("--------分割线--------")
print(a[1])
print(a[-3])
print("--------分割线--------")
print(a[2])
print(a[-2])
print("--------分割线--------")
print(a[3])
print(a[-1])

输出

你
你
--------分割线--------
好
好
--------分割线--------
啊
啊
--------分割线--------
吗
吗

1.2、切片(Slicing)

切片操作是访问序列中的元素的另一种方法
语法格式:

sname[start : end : step]

说明:
1、sname:序列的名字
2、start:切片的起始位置(包括该位置),如果不指定,默认为0
3、end:切片的截止位置(不包括该位置),如果不知道,默认为序列的长度
4、step: 切片的步长,如果省略(省略时可以连最后一个冒号也一起省略),默认为1。

如:

animal = ["小马", "小牛", "小羊", "小狗", "小猴", "小猫", "小蛇", "小虎", "小兔"]
print(animal[1:5])
print(animal[2:5:2])

输出

['小牛', '小羊', '小狗', '小猴']
['小羊', '小猴']

技巧:如果需要复制一整个序列,可以将start,end都有省略,但是中间的冒号要保留。如

animal[ : ]

1.3、序列相加与相乘

1、序列相加
可以将2个同类型(同为列表、元组、字典等,序列里的元素类型可以不同)的序列进行相加操作(使用+号进行),其实就是拼接2个序列

2、序列相乘
一个序列乘以数字n,那么就将序列重复n次成为新的序列。
如

animal = ["小马", "小牛", "小羊"]
print(animal * 3)

输出

['小马', '小牛', '小羊', '小马', '小牛', '小羊', '小马', '小牛', '小羊']

如果只是为了初始化指定列表长度的功能,那么可以采取以下方式
如

a = [None] * 5
print(a)

输出

[None, None, None, None, None]

1.4、检查某个元素是否是序列的成员(元素)

可以使用in关键字来检查
语法格式:

value in sequence

例子

animal = ["小马", "小牛", "小羊"]
print("小马" in animal)
print("xiaoma" in animal)
print("xiaoma" not in animal)

输出

True
False
True

1.5、计算序列的长度、最大值和最小值

计算序列的长度使用内置函数len()、最大值使用内置函数max()和最小值使用内置函数min()
如:

a = ["1", "5", "2"]
print("a序列的长度", len(a))
print("a序列的最大元素", max(a))
print("a序列的最小元素", min(a))

输出

a序列的长度 3
a序列的最大元素 5
a序列的最小元素 1

python中的其他内置函数及其作用

函数 作用
list() 将序列转化为列表
str 将序列转化为字符串
sum() 计算元素和
sorted 对元素进行排序
reversed() 反向序列元素
enumerate() 将序列组合为一个索引序列,多用在for循环中

如

a = ["1", "5", "2"]
print("[1,2,3]序列的元素和", sum([1,2,3]))
print("正序", sorted(a, reverse=True))
print("逆序", sorted(a, reverse=False))

2、列表(list)

python中的列表是非常灵活的,列表里的元素内容可以不同,因为他们之间没有任何关系,但是通常情况下我们在一个列表里只放一种数据类型,为得是增加数据的可读性

2.1、创建与删除列表

1、使用赋值运算符直接创建列表
语法格式如下:

listname = [element 1, element 2, ......, element n]      

2、创建空列表
语法如下:

emptylist = []

3、创建数值列表
可以使用list()函数直接将range()函数循环出口的结果直接转换为列表
语法如下:(其中data的类型可以是range对象、字符串、元组或者其他可以迭代类型的数据)

list(data)

例子:

print(list(range(10)))

输出

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

4、删除列表
语法格式:

del listname

值得注意的是在python中有自带的垃圾回收机制会自动销毁不用的列表,故该语句我们比较少用。

2.2、访问列表元素

输出列表或者列表的某个元素的语法格式:

print(listname)或者print(listname[n])

2.3、遍历列表

遍历列表的方法很多,这边介绍2种最常用的

1、使用for循环
语法格式:

for item in listname:
    # 输出item

例子:

fruit = ['apple', 'banana', 'orange', 'pear', 'watermelon']
for i in fruit:
    print(i)

输出

apple
banana
orange
pear
watermelon

2、使用for循环和enumerate()函数实现
使用for循环和enumerate()函数实现输出索引和元素
语法格式:

for index, item in enumerate(listname):

例子

fruit = ['apple', 'banana', 'orange', 'pear', 'watermelon']
for index,i in enumerate(fruit):
    print(index, i)

输出

0 apple
1 banana
2 orange
3 pear
4 watermelon

2.4、添加、删除、修改列表元素

1、添加元素
语法格式如下:

listname.append(obj)    #速度快,常用
或者
使用+号,                #速度太慢
或者
insert()函数            #效率低,不推荐

例子:

fruit = ['apple', 'banana', 'orange', 'pear', 'watermelon']
print("水果的种类有" + str(len(fruit)) + '种')
fruit.append("grape")
print("水果的种类有"+ str(len(fruit)) + '种')

输出

水果的种类有5种
水果的种类有6种

如果要将一个列表里的元素全部添加到另一个列表
可以使用下面语句:

listname.extend(seq)         #seq为要添加进去的列表

2、修改元素
直接举例子说明

fruit = ['apple', 'banana', 'orange', 'pear', 'watermelon']
print(fruit)
fruit[2] = 'strawberry'
print(fruit)

输出

['apple', 'banana', 'orange', 'pear', 'watermelon']
['apple', 'banana', 'strawberry', 'pear', 'watermelon']

3、删除元素

(1)、根据索引删除

如:

fruit = ['apple', 'banana', 'orange', 'pear', 'watermelon']
del fruit[1]
print(fruit)

输出

['apple', 'orange', 'pear', 'watermelon']

(2)、根据元素值删除

如:

fruit = ['apple', 'banana', 'orange', 'pear', 'watermelon']
value = "apple"
if fruit.count(value) > 0:    # 判断元素是否存在防止报错
    fruit.remove(value)
print(fruit)

输出

['banana', 'orange', 'pear', 'watermelon']

2.5、对列表进行统计计算

1、获取指定元素出现的次数
使用count()函数
语法格式:

listname.count(obj)

2、获取指定元素首次出现的下标
使用index()函数
语法格式:

listname.index(obj)

3、统计数值列表的元素和
使用sum()函数

sum(iterable[,strart])    #iterable为要统计的列表名

2.6、对列表进行排序

1、使用sort函数进行排序
语法格式:

listname.sort(key=None,reverse=False)

参数说明,key是指定一个比较键,如当key=str.lower时,不区分大小写。
reverse=False时为降序,为True时为升序,默认为升序。

注意sort()函数对字符串进行排序时,先对大写字母进行排序,然后对小写字母进行排序。且对中文排序时,容易出错
如

fruit = ['Apple', 'banana', 'Orange', 'pear', 'watermelon']
print('-------区分大小写-------')
fruit.sort()
print(fruit)
print('-------不区分大小写-------')
fruit.sort(key=str.lower)
print(fruit)

输出
——-区分大小写——-

['Apple', 'Orange', 'banana', 'pear', 'watermelon']
-------不区分大小写-------
['Apple', 'banana', 'Orange', 'pear', 'watermelon']

2、使用sorted()函数进行排序
作用与sort()基本一样,但是sorted()不会改变原列表的顺序,sort()会。
语法格式:

sorted(iterable, key=None,reverse=False)   #iterable为要排序的列表

如

fruit = ['Apple', 'banana', 'Orange', 'pear', 'watermelon']
fruit_a = sorted(fruit)
print("原列表顺序不变", fruit)
print(fruit_a)

输出

原列表顺序不变 ['Apple', 'banana', 'Orange', 'pear', 'watermelon']
['Apple', 'Orange', 'banana', 'pear', 'watermelon']

2.7、列表推导式

使用列表推导式可以快速生成一个列表,或让摸个列表生成满足指定需求的列表。
有以下几种常用方法
1、生成指定范围的数值列表
语法格式:
list = [Expression for var in range]

参数说明:list生成的列表名,Expression表达式用于计算新列表的元素
var循环变量,range采用range()生成的range对象
如生产10个随机数,范围在10到100之间

import random
randomnumber = [random.randint(10,100) for i in range(10)]
print(randomnumber)

输出

[65, 50, 57, 84, 56, 30, 27, 47, 98, 79]

2、根据列表生成指定需求的列表
语法格式:

newlist = [Expression for var in list]

如

import random
price = [100, 200, 300]           # 商品价格
sale = [int(i*0.5) for i in price]      # 打五折后的价格
print(sale)

输出

[50, 100, 150]

3、从列表中选择符合条件的元素组成新的列表
语法格式:

newlist = [Expression for var in list if condition]
如
import random
price = [100, 200, 300]           # 商品价格
sale = [i for i in price if i > 200]      # 价格大于200的商品价格
print(sale)

输出

[300]

3、元组

元组简单说就是不可变的列表(不可变序),用于保存不可修改的内容。

3.1、元组的创建与删除

1、用赋值运算符直接创建元组
语法格式(括号可以省略)

tuplename = (element 1,element 2,...element n)

如果创建的元组只有一个符号时,需要在元素的后面加个逗号
如:

a = ("a",)   # 元组
a = ("a")    # 字符串

2、创建空元组
语法格式

emptytuple = ()

3、创建数值元组
语法格式

tuple(data)

如

print(tuple(range(0, 10, 3)))

输出

(0, 3, 6, 9)

4、删除元组
语法格式

del tuplename

3.2、访问元组元素

print直接打印元组
语法格式

print(tuplename)         #打印整个元组
print(tuplename[n])      #打印单个元组元素
print(tuplement[x:y])    #打印多个元素

当然也可以使用for循环来遍历,语法格式与列表一样

3.3、修改元组元素

修改元组里的单个元素的内容,是不支持的
如

a = (1,2,3)
a[1]= "a"
print(a)

报错

TypeError: 'tuple' object does not support item assignment

但是我们可以把一整个元组重新赋值
如

a = ('1', 2, 3)
print(a)
a = ('1', 6, 9)
print(a)
a = a+a
print(a)

输出

('1', 2, 3)
('1', 6, 9)
('1', 6, 9, '1', 6, 9)

注意进行元组的连接时,连接的内容必须都是元组。连接的元组只有一个元素时,不用忘记元素后面的逗号。

3.4、元组的推导式

语法格式与列表类似

例子

import random
randomname = (random.randint(10,100) for i in range(5))
print("生产的元组为", randomname)

输出

生产的元组为 <generator object <genexpr> at 0x000001C573448E60>

可以发现元组推导式生成的结果是一个生成器对象,而不是元组或者列表。这点与列表不同。其中转化成元组用tuple()函数,转化为列表用list函数

通过for循环遍历,或者使用next()方法可以使用元组推导器生成的生成器对象

如:(next()例子)

import random
randomname = (i for i in range(3))
print(randomname.__next__())
print(randomname.__next__())
print(randomname.__next__())
print(tuple(randomname))

输出

0
1
2
()

如(for循环遍历例子)

import random
randomname = (i for i in range(3))
for i in randomname:
    print(i, end=" ")
print(tuple(randomname))

输出

0 1 2 ()

3.5、元组与列表的区别

1、元组不可变序列;列表可变序列

2、元组不能修改、添加,删除单个元素;列表可以

3、元组只支持切片访问,不支持切片修改;列表都支持

4、元组访问和处理速度比列表快。使用当只需要对其中的元素进行访问时,,建议使用元组

5、元组可以作为字典的键;列表不能。

4、字典

字典是无序的可变序列。保存内容是以“键—值对”的形式存放,键是唯一的,值可以是多个的。

字典的主要特征:
1、通过键来读取而不是索引

2、字典是任意对象的无序集合

3、字典是可变的,并且可以任意嵌套。

4、字典的键必须是唯一和不可变的。

4.1、字典的创建与删除

创建字典语法格式

dictionary = {'key1':'value1','key1':'value1',...,'keyn':'valuen',}

创建空字典的语法

dictionary = {}或者dictionary = dict()

1、通过映射函数创建字典

dicttionary = dict(zip(list1,list2))   #list1作为键的列表  list2作为值的列表

注意如果list1与list2长度不一样,则与最短的列表长度一样

2、通过“键——值对”创建字典

dictionary = dict(key1=value1,key2=value2,...,keyn=value n)

如

a = dict(福州='3',)
print(a)

输出

{'福州': '3'}

python中还可以使用dict对象的fromkeys()方法创建值为空的字典
语法格式:

dictionary = dict.fromkeys(list1)   #list1为键的列表

当然还有可以通过存在的元组和列表来创建字典(列表不能作为键,字典可以)
如

list = [1, 2, 3]
b = ('1', '2', '3')
c = {b: list}
print(c)

输出

{('1', '2', '3'): [1, 2, 3]}

3、删除字典
语法格式

del dictionary

4、把字典变为空字典
语法格式

dictionary.clear()

当然还有pop(),popitem()方法。

4.2、通过键—值对访问字典

如果想直接输出字典的内容直接printf(dictionary),但是我们一般不这么做。一般是根据指定的键得到我们想要的结果。
如

print(dictionary([key])

但是这样容易出错,我们一般使用以下语句

print(dictionary[key] if  'key ' in dictionary else '我的字典里没有该内容')

python中推荐使用字典对象的get()方法获取指定的键的值
语法格式如下:

dictionary.get(key,[default])

说明defaults是当指定的键不存的时候就返回一个默认值,default可以省略,如果省略返回None

4.3、遍历字典

1、通过items()方法遍历
语法格式:

dictionary.items()  #返回可以遍历的j键-值元组列表

2、for循环遍历该元组列表
如

dictionary = {'qq':'12333'}
for i in dictionary.items():
    print(i)
    或
for key,value in dictionary():
    print(value)

4.4、添加、修改、删除字典元素

1、添加元素
语法格式

dictionary[key] = value

注意如果键名之前已经存在,那么将换替换该键的值

2、删除某个元素
如:

dictionary = dict[key]
或者
if "key" in dictionary:    #防止键不存在时报错
    dictionary = dict[key]

4.5、字典推导式

其表现形式与列表推导式相似,这边不做说明

5、列表、元组、字典的区别

数据结构 是否可变 是否有序 定义符号
列表 可变 有序 []
元组 不可变 有序 ()
字典 可变 无序 {key,value}

题目:创建一个包含1~50之间所有素数的列表,打印显示该列表;随后只保留该列表前5个数字,删除其余内容并打印输出相应结果;再将每个元素值加。上20,显示列表内容。

prime_number = [2]
for i in range(3, 51):
    for j in range(2, i):
        if i % j != 0:
            n = i
            if j == n-1:
                prime_number.append(i)
                break
        else:
            break
print(prime_number)
prime_number = prime_number[:5]
for k in range(5):
    prime_number[k] = prime_number[k] + 20
print(prime_number)

6、逻辑判断内置函数

all(iterable) 集合中的元素都为真的时候为真,注意空字串返回为True
any(iterable) 集合中的元素有一个为真的时候为真,特别是空串返回False
cmp(x,y) x<y,返回负数;x = y,返回0;x>y返回正数

python知识整合(基础)

发表于 2019-09-12 | 分类于 python

本文章内容的python版本默认为python3.x

1、注释

注释包括单行注释,多行注释,中文声明注释

1.1、单行注释

注释内容从#号到换行为止结束
语法格式:

# 注释内容

注释格式:
第一种

#请输入你的年龄
age=int(input("请输入你的年龄"))

第二种

age=int(input("请输入你的年龄"))        #请输入你的年龄

1.2、多行注释

在python中没有一个单独的多行注释标记,而是将注释内容包含在一对(‘’’…..’’’’)或者(”””…”””)
语法格式:

'''
注释内容1
注释内容2
......
'''

或者

"""
注释内容1
注释内容2
......
"""

当然可以利用单行注释实现多行注释,如

#注释内容1
#注释内容2
#....

1.3、中文编码声明注释

在python编写时,如果要指定字符编码,那么就需要在文件开头加上中文编码声明注释,来指定我们所需要的字符编码类型的中文编码,可以避免输出乱码
语法格式:

#-*- coding:编码-*-

或者

#  coding=编码

如

# coding=utf-8

==值得注意的是==,上面代码中的-*-是为了美观才加上的,没有任务特殊作用,故也可写为 # coding:编码

2、代码缩进

python中使用代码缩进来区分代码的层次感,这点与c等一些语言不一样。

缩进可以使用空格键或者tap键,通常一个缩进量默认为为4个空格(可以修改),一个tap键为4个空格,不过,建议使用空格进行缩进。

注意:python中对代码缩进的要求非常严格,同一个级别的代码块的缩进量必须是相同的,否则将出现语法错误(SyntaxError)

3、代码规范

3.1、编写规则

pthon采用的是PEP8的编码规范,PEP是python Enhancement Proposal的缩写,8为版本

使用import进行导入模块时,注意,一次只导入一个模块。
推荐写法:

import os
import request

不推荐写法:

import os , request

不要在行尾添加“;”,也不用将2条命令放在同一行,然后用“;”隔开。python中换行代表中一个语句的结束。

建议每行不超过80个字,如果超过用()连接,不推荐”\”
如,推荐

print("是多少级看过的力合股份客户广泛空间看过空间看过很快就卡。"
            "夫卡的风格看看吃饭大概开发地方")

不推荐

print("是多少级看过的力合股份客户广泛空间看过空间看过很快就卡。\
            "夫卡的风格看看吃饭大概开发地方")

特殊情况除外
1.导入模块语句过长
2.注释里的URL

可以使用空行增加代码的可读性,如·在定义方法之间空一行等等。

3.2.命名规范

1、模块名尽量短小,且全部小写,可以使用下划线,如

game_age

2、包名尽量短小,且全部小写,不推荐使用下划线,如

com.book

3、类名采用单词首写字母大即是Pascal风格。如

BorrowBook

4、内部模块采用下划线加Pascal风格命名,如

_BorrowBook

5、函数、类的属性和方法的命令规则和模块类似

6、常量命名时全部大写,使用可以使用下划线

注意:
使用单下划线开头的模块变量或函数是受保护的,在使用import*from语句从模块中不能导入。
使用双下划线开头的实例变量或方法是类私有的。

4、基本的输入与输出

4.1、print()函数

print()基础语法:

print("输出内容")

注意print()语句输出后会自动换行,如果要一次输出多个内容,且不换行,可以用英文的半角逗号进行分开。如

print("a","b")

输出结果为a b

输出时间
如

import datetime                          # 调用时间模块datetime
d=datetime.datetime.now()
print(d)                                 # 输出当前日期和时间
print(d.strftime('%Y-%m-%d %H:%M:%S'))   # 按格式输出当前时间
print(d.strftime('%I:%M %p'))      

print()不仅仅可以输出内容到屏幕还可以输出到指定文件
如

fp = open(r'F:\my.txt','a+')    # 打开文件,如果没有该文件将自动创建文件
print("hello world",file=fp)    # 输出到文件中
fp.close()                      # 关闭文件

4.2、input()函数

作用:input()在python中可以用来接收用户键盘输入的内容

如:

b = input("输入字符:")
print(b+"的ASCII码为",ord(b))

输出结果为:

输入字符:b            # b为我们输入的字符
b的ASCII码为 98

例子:根据输入的年份计算年龄

import datetime                                 # 调入时间模块datetime
imyear = input("请输入你的出生年份")               # 输入四位数的出生年份
nowyear = datetime.datetime.now().year          # 获取当前的年份
age = int(nowyear) - int(imyear)                # 计算年龄
print("你的年龄为"+str(age))

注意判断一个变量的类型可以使用type()函数

例子:查单个字符的ACSII码器

b = 12
while b>0:
    a = input("请输入字符:")
    print(a + "的ASCII码为", +ord(a))

5、保留字与标识符

5.1、保留字

保留字就是被赋予特定意义的一些单词,这些单词不能被当作变量、函数、类、模块和其他对象的名称来使用(否则会报invalid syntax错误),python中保留字是区分大小写的,

python中的保留字,这边全部列出
| and | as | assert | break | class |
| ——– | —— | —— | —– | —— |
| continue | def | del | elif | except |
| finally | for | from | False | global |
| if | import | in | is | lambda |
| nonlocal | or | pass | raise | return |
| try | True | while | with | yield |

当然如果我们忘记了也不用紧,可以通过2行代码查看保留字

import keyword
print(keyword.kwlist)

5.2、标识符

简单说标识符就是一个名字,用来识别变量、函数、类、模块和其他对象的名称。

命名规则
1、由字母、下划线和数字组成,并且第一个字母不能是数字。目前python中只允许使用ISO-Latin字符集中的字符A-Z和a~z.
2、不能使用Python中的保留字
例如,合法标识符

USSSS
name
name123
name_age

不合法标识符

4name             # 不能以数字开头
if                # 不能以保留字当作标识符
$name              #  不能使用特殊字符 空格、$、@、%等

3、区分字母大小写

4、以下划线开头的标识符具有特殊意义,要避免使用类似的标识符

以单下划线开头的标识符表示不能直接访问的类的属性,也不能太过from xxx import *导入

以双下划线开头的标识符表示类的私有成员

以双下划线开头和结尾的标识符是python中专用的标识,如int()表示构造函数

5、尽量避免使用汉字作为标识符,尽管这是被允许的。

6、变量

6.1、变量的命名规则与语法格式

变量的命名规则

1、变量名必须是一个有效的标识符

2、变量名不能使用python中的保留字

3、慎用小写字母 l 和大写字母O

4、应该选择有意义的单词作为变量名

语法格式

变量名 = value     #变量赋值
如
name = 12         # 创建变量name并赋值为12,类型为int
name = "John"     # 创建变量name并赋值为John,类型为str

注意,python中允许多个变量指向同一个值,但是他们对于的内存地址是否相同呢同,我们可以是内置函数id()来查看

例如

a = 2014
b = 2014
print("a的地址为",+id(a))
print("b的地址为",+id(b))

输出

a的地址为 2316677533424
b的地址为 2316677533424

7、基本数据类型

7.1、数字类型

1、整数
整数包括,十进制、八进制、十六进制

十进制不能以0开头

八进制在python3.x中必须以0o或0O开头,python2.x可以以0开头

十六进制必须以0x或0X开头

2、浮点数
浮点数表现形式,如2.7e2(科学计数法),1.1414

值得注意的是在使用浮点数进行计算时,可能会出现小数位数不确定的情况,如

a = 0.2
b = 0.1
c= a + b
print(c)

我们觉得输出0.3,但是实际输出0.30000000000000004,
所有语言都有这个问题,可以忽略对于的小数位

3、复数
在python中复数与数学中的复数在形式上完全一样

7.2、字符串类型

在python中字符串属于不可变序列
通常用单引号,双引号,三引号括起来。其中三引号内的字符序列可以分布在连续的多行中,而单引号,双引号内的字符序列必须在一行中。

注意如果需要表示复杂的字符串时可以进行引号的嵌套
如;

print(''''___' "_"***''')

输出

'___' "_"***

python中的字符串还支持转义字符
常见的转义字符如下表
| \ | 续行符 |
| —- | ———————————— |
| \n | 换行符 |
| \r | 回车符 |
| \0 | 空 |
| \t | 水平制表,用于横向跳到下一制表位 |
| \ “ | 双引号 |
| \ ‘ | 单引号 |
| \ | 一个反斜杠 |
| \f | 换页 |
| \0dd | 八进制数,dd表示字符,如\012代表换行 |
| \xhh | 十六进制,hh表示字符,如\x0a代表换行 |

注意在字符串定界符引号的前面加上R或r,将无视转义字符的存在。
如

print(r"hello\nworld")
print("hello\nworld")

输出

hello\nworld
hello
world

7.3、布尔类型

标识符True和False为布尔类型
True表示1,False表示0

注意布尔类型可以进行运算但是不建议进行运算

在python中所有对象都可以进行真假测试,只有以下几种情况为假其他都为真。
1、False或None

2、数值中的零,包括0、0.0、序数0

3、空序列,包括字符串,空元组、空列表、空字典

4、自定义对象的实例,对象的bool方法返回False或者len方法返回0.

7.4、数据类型转换

python是动态类型语言(也就是弱类型语言),不需要先声明变量类型,但在对变量进行操作时可能用到类型转换。

常用的类型转换函数
| 函数 | 作用 |
| ——————– | ————————————————– |
| int(x) | 将x转为整型 |
| float(x) | 将x转为浮点型 |
| complex(real[,imag]) | 创建一个复数 |
| str(x) | 将x转为字符串 |
| repr(x) | 将x转为表达式字符型 |
| eval(str) | 计算在字符串中的有效的python表达式,并返回一个对象 |
| chr(x) | 将整数x转为字符 |
| ord(x) | 将一个字符返回其所对应的整数值 |
| hex(x) | 将一个整数转化为一个16进制字符串 |
| oct(x) | 将一个整数转化为一个8进制字符串 |

8、运算符

8.1、算术运算符

加(+)、减(-)、乘(*)、除(/)、取余数(%)、取整除(//)、幂(**)

注意
1、在%中如果除数(第二个操作数)是负数,那么得到的结果也是负数

2、使用/或//时,除数不能为0,不然会出现错误

3、在python2.x中/符号计算的结果为整数,而在python3.x中为浮点数,如
3/2,在python2.x中为1,在在python3.x中为1.5

8.2、赋值运算符

常见的赋值运算符有=、+=、-=、*=、/=、%=、**=、//=等
在使用时,就是把=号右边的值赋值给左边的变量,也可以进行某些运算后再赋值给左边的变量。
如x-=y,就是等于x=x-y,
例子如下

x = 1
y = 2
x -= y
print(x)

输出x=-1

8.3、比较(关系运算符)

对表达式或者变量的结果进行大小、真假等比较,如果比较结果为真返回True,否则为False

比较运算符有:

>、 < 、==、!=、>=、<=

如果要判断一个变量是否在一个范围内可以使用 “ 值1<变量a<值2 ”

8.4、逻辑运算符

主要包括 and(逻辑与) or(逻辑或) not(逻辑非)
and和or 的结合方向是从左到右
not的不一样是从右到左

8.5、位运算符

位运算符是对二进制进行计算的,所以需要把要执行的数据转化为二进制数,然后再进行位操作。
python中位运算符有位与(&)、位或(|)、位异或(^)、位取反(~)、位左移(<<)、位右移(>>),

位运算符名称 算法
位与(&) 2个二进制数的对位都为1时才为1,否则为0 ,若2个操作数精度不同,则结果的精度与精度高的操作数相同
位或 2个二进制数的对位都为0时才为0,否则为1,若2个操作数精度不同,则结果的精度与精度高的操作数相同
位异或(^) 2个二进制数的对位相同时才为0,否则为1 ,若2个操作数精度不同,则结果的精度与精度高的操作数相同
位取反(~) 操作数中的1改为0,0改为1
位左移(<<) 将一个二进制操作数左移指定的位数,左边(高位段)溢出的位丢低,右边(低位段)的空位用0补充,位左移运算相当于乘以2的n次幂
右移(>>) 将一个二进制操作数右移指定的位数,右边(低位段)溢出的位用丢低,而在左边(高位段)的空位补充时,如果最高位为0,则在左侧补0,否则补1。位右移运算相当于除以2的n次幂

注意:
由于移位运算符运算速度很快,所有在程序中遇到表达式乘以或除以2的n次幂时可以用移位运算符来代替

8.6、运算符的优先级

python中运算符的运算规则是,优先级高的先执行,低的后执行,同一级的按从左往右进行操作。当然如果有括号,括号内的运算最先执行。在编写程序时尽量使用括号()来限定运算次序,以免运算次序出错
运算符的优先级(从高到低)
| 类型 |
| ———————————- |
| * |
| ~、+、- |
|
、/、%、// |
| +、- |
| <<、>> |
| ^ |
| 位或 |
| <、<=、>>、=!、=、==(比较运算符) |

9、流程控制语句

9.1、选择语句

1、最简单的if语句
语法结构如下:

if 表达式:
    语句块

注意在python中,当表达式的值为非零或者非空的字符串时。if语句也认为是条件成立(为真值)
2、if…else语句
语法结构如下:

if 表达式:
    语句块1
else:
    语句块2

技巧:
if…else语句可以使用条件语句进行简化,如

a = 1
if a > 0:
    b =a
else:
    b = -a
print(b)

可以简化为(就是使用条件表达式)

a = 1
b = a if a > 0 else -a
print(b)

3、if…elif…else语句
语法结构

if  表达式1:
    语句块1
elif 表达式2:
    语句块2
elif 表达式3:
    语句块3
...
else:
    语句块n

注意:if与elif都需要进行判断真假,而else不需要判断;else和elif都需要与if一起使用,不能单独使用

4、if语句的嵌套
if选择语句可以有多种嵌套方式,根据需要灵活运用。
如

if 表达式1:
    if 表达式2:
        语句块1
    else:
        语句块2

9.2、循环语句

循环体就是一组被重复执行的语句。
1、whie循环
while循环结构

while 条件表达式:
    循环体

值得注意的是Python不支持do〜while语法、while(无限循环)和break组合起来替换 do ~ while
如

n = 0
while True:         #无限循环...     
      print n
      n += 1
      if n == 10:
             break     #结束循环    

2、for循环
for循环结构

for 迭代变量 in 对象:
    循环体

如:

print("技术1+2+3+...+100结果为:")
result = 0
for i in range(101):
    result += i
print(result)

对range()这个函数进行简单的说明

range(start,end,step)

start为计数的起始值,可以省略,省略就从0开始

end为计数的结束值,但是不包括该值,如range(5),会输出0,1,2,3,4,不可省略

step为计数的步长,就是2个参数之间的间隔,可以省略,省略就默认为1

小技巧
在python3.x中,如果让print语句输出的内容在一行上可以使用下面这个语句

print(result,end=' 分隔符 ')

for语句不仅可以循环数值,还可以逐个遍历字符串。

当然可以进行循环嵌套

9.3、跳转语句和pass空语句

1.break语句
break语句通常会结合if语句使用,在某种条件下跳出循环。如果是嵌套循环,那么break语句将跳出最内层的循环

如while语句中使用break语句

while 条件表达式1:
    执行代码
    if 条件表达式2:
        break

for语句中使用break语句

for 迭代变量 in 变量
    if 条件表达式:
        break

2.continue语句
break语句通常会结合if语句使用,在某种条件下跳出当次循环,进行下一次循环。如果是嵌套循环,那么break语句将跳出最内层的当次循环

如while语句中使用break语句

while 条件表达式1:
    执行代码
    if 条件表达式2:
        continue

for语句中使用break语句

for 迭代变量 in 变量
    if 条件表达式:
        continue

3、pass空语句
不做任何事,一般起到占位作用,为得是方便以后进行处理

for 迭代变量 in 变量
       if 条件表达式:
           语句块
       else:
           pass

10、数字运算类内置函数

函数名 作用
abs(x) 求绝对值,参数可以是整数,也可以是复数,复数就输出复数的模
oct(x) 将一个数字转为8进制字符串
hex(x) 将一个数字转为16进制字符串
chr(x) 返回整数x对应的ASCII的字符
ord(x) 返回x对应的ASCII的值
complex([real[,image]]) 创建一个复数
divmod(a,b) 分别取商和余数,整数和浮点数都可以
float(x) 将x转化为浮点数,如果没有参数返回0.0
int([x[,base]]) 将x转化为int型,base为进制
long([x[,base]]) 将x转化为long型,base为进制
pow(x,y[,z]) 返回x的y次幂
range(strat,stop[,step]) 产生一个序列,默认从零开始
round(x[,n]) 四舍五如=入
sum(iterable[,start]) 对集合求和
bin(x) 将整数x转化为二进制字符串
bool([x]) 将x转化为布尔类型
12…5
wr

wr

47 日志
10 分类
6 标签
© 2020 wr
由 Hexo 强力驱动 v3.8.0
|
主题 – NexT.Gemini v7.0.0
|
0%