Python入门自学——python简介

Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言。

Python是一种解释型语言,是在执行时一行一行地翻译成CPU能理解的机器码,相对的是编译型语言,在执行前编译成机器码,所以,python的第一个缺点就是运行速度慢,第二个缺点就是代码不能加密。如果要发布你的Python程序,实际上就是发布源代码。解释型的语言,都则必须把源码发布出去,但不要担心这个问题。

Python适合开发哪些类型的应用呢?首选是网络应用,包括网站、后台服务等等;其次是许多日常需要的小工具,包括系统管理员需要的脚本任务等等;另外就是把其他语言开发的程序再包装起来,方便使用。

对于编程语言,还有动态语言和静态语言之分:

动态:变量的类型是在第一次赋值给变量时根据数据类型赋类型。

静态:在编译期间就进行数据类型检查。

还有强类型定义语言和弱类型定义语言之分。

一、python的安装

python的版本演进过程:

Python的版本2.X ——2.7——3.X,版本2和版本3是不兼容的,其中2.7是特殊的中间版本,其支持2.0和3.0的语法。

Windows环境下:下载

可以看到,3.9版本是不能运行在win7及以前的操作系统下的。安装Windows版的Python,有几种版本:下面是网络上的一种流行解释:

python安装包下载  embeddable zip file 、executable、web-based  的区别:

1、embeddable zip file: zip 压缩档,就是python打包成zip压缩包。下载后拷到电脑上解压就直接用,无需安装。一般资深的程序员会用。

2、executable: 可執行文件的,既把要安装的python全部下载好在本机安装。

3、web-based: 透过网络安装的,安装过程需要网络来支持(在线安装),网速不好时可以慢慢装。

X86和X86-64的区别: 32 bit 的版本和 64 bit 的版本。

对于embeddable,其解压后与使用excutable大小比较后,发现embeddable小的多。我理解enbeddable是一种嵌入式的版本,可以理解成最小资源版本,适用于嵌入式系统。

安装后,在cmd命令窗口下运行python无法运行,在系统变量或用户变量Path中添加python路径。

在windows下安装executable版本后,在开始菜单栏中增加如下项:

上图左边是直接运行python 3.8(64-bit)的图,右边是IDLE的图,左边就相当于先打开CMD窗口,然后执行python命令

在python的交互窗口 >>>下运行python命令、函数等代码,直接解释执行

将代码保存在文本文件中,使用python d:\pythoncode\hello.txt 也可以运行代码。

另一种方法是保存为.py文件,直接双击运行,或者如上面的使用python wenjianming.py运行。

python的解析器:CPython、IPython、PyPy、Jython、IronPython。

CPython:这个解释器是用C语言开发的,所以叫CPython,是官方版本的解释器。

Python的解释器很多,但使用最广泛的还是CPython。如果要和Java或.Net平台交互,最好的办法不是用Jython或IronPython,而是通过网络调用来交互,确保各程序之间的独立性

linux上是默认自带有python的,试着装了一个centos7,里面的python是2.7版本的。

二、第一个python程序

交互窗口下:

命令窗口运行文件模式:

一般都是写成.py后缀。

文本编辑器使用Visual Studio Code!

Python在线运行代码助手:

可以以网页形式运行python代码,具体是运行一个python程序,启动一个类似web的服务,然后在本地使用IE或其他浏览器打开,下面是learning.py的完整代码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
 
r'''
learning.py
 
A Python 3 tutorial from http://www.liaoxuefeng.com
 
Usage:
 
python3 learning.py
'''
 
import sys
 
def check_version():
 v = sys.version_info
 if v.major == 3 and v.minor >= 4:
  return True
 print('Your current python is %d.%d. Please use Python 3.4.' % (v.major, v.minor))
 return False
 
if not check_version():
 exit(1)
 
import os, io, json, subprocess, tempfile
from urllib import parse
from wsgiref.simple_server import make_server
 
EXEC = sys.executable
PORT = 39093
HOST = 'local.liaoxuefeng.com:%d' % PORT
TEMP = tempfile.mkdtemp(suffix='_py', prefix='learn_python_')
INDEX = 0
 
def main():
 httpd = make_server('127.0.0.1', PORT, application)
 print('Ready for Python code on port %d...' % PORT)
 httpd.serve_forever()
 
def get_name():
 global INDEX
 INDEX = INDEX + 1
 return 'test_%d' % INDEX
 
def write_py(name, code):
 fpath = os.path.join(TEMP, '%s.py' % name)
 with open(fpath, 'w', encoding='utf-8') as f:
  f.write(code)
 print('Code wrote to: %s' % fpath)
 return fpath
 
def decode(s):
 try:
  return s.decode('utf-8')
 except UnicodeDecodeError:
  return s.decode('gbk')
 
def application(environ, start_response):
 host = environ.get('HTTP_HOST')
 method = environ.get('REQUEST_METHOD')
 path = environ.get('PATH_INFO')
 if method == 'GET' and path == '/':
  start_response('200 OK', [('Content-Type', 'text/html')])
  return [b'<html><head><title>Learning Python</title></head><body><form method="post" action="/run"><textarea name="code" style="width:90%;height: 600px"></textarea><p><button type="submit">Run</button></p></form></body></html>']
 if method == 'GET' and path == '/env':
  start_response('200 OK', [('Content-Type', 'text/html')])
  L = [b'<html><head><title>ENV</title></head><body>']
  for k, v in environ.items():
   p = '<p>%s = %s' % (k, str(v))
   L.append(p.encode('utf-8'))
  L.append(b'</html>')
  return L
 if host != HOST or method != 'POST' or path != '/run' or not environ.get('CONTENT_TYPE', '').lower().startswith('application/x-www-form-urlencoded'):
  start_response('400 Bad Request', [('Content-Type', 'application/json')])
  return [b'{"error":"bad_request"}']
 s = environ['wsgi.input'].read(int(environ['CONTENT_LENGTH']))
 qs = parse.parse_qs(s.decode('utf-8'))
 if not 'code' in qs:
  start_response('400 Bad Request', [('Content-Type', 'application/json')])
  return [b'{"error":"invalid_params"}']
 name = qs['name'][0] if 'name' in qs else get_name()
 code = qs['code'][0]
 headers = [('Content-Type', 'application/json')]
 origin = environ.get('HTTP_ORIGIN', '')
 if origin.find('.liaoxuefeng.com') == -1:
  start_response('400 Bad Request', [('Content-Type', 'application/json')])
  return [b'{"error":"invalid_origin"}']
 headers.append(('Access-Control-Allow-Origin', origin))
 start_response('200 OK', headers)
 r = dict()
 try:
  fpath = write_py(name, code)
  print('Execute: %s %s' % (EXEC, fpath))
  r['output'] = decode(subprocess.check_output([EXEC, fpath], stderr=subprocess.STDOUT, timeout=5))
 except subprocess.CalledProcessError as e:
  r = dict(error='Exception', output=decode(e.output))
 except subprocess.TimeoutExpired as e:
  r = dict(error='Timeout', output='执行超时')
 except subprocess.CalledProcessError as e:
  r = dict(error='Error', output='执行错误')
 print('Execute done.')
 return [json.dumps(r).encode('utf-8')]
 
if __name__ == '__main__':
 main()

运行:

然后打开地址:

我测试时出现错误:

不知道什么问题。

三、输入和输出:

输出使用print()函数,在括号中加上字符串,就可以向屏幕上输出指定的文字。如print('hello, world')。也可以接受多个字符串,用逗号“,”隔开,就可以连成一串输出:

>>> print('The quick brown fox', 'jumps over', 'the lazy dog')
The quick brown fox jumps over the lazy dog

print()会依次打印每个字符串,遇到逗号“,”会输出一个空格,因此,输出的字符串是这样拼起来的:

print-explain

输入使用input(),让用户输入字符串,并存放到一个变量里。

输入完成后,不会有任何提示,Python交互式命令行又回到>>>状态了。那刚才输入的内容到哪去了?答案是存放到name变量里了。可以直接输入name查看变量内容。

要注意的重点是输入的内容作为字符串类型,即使是输入的数字123,也是作为字符串,不能直接进行算数运算。

四、Python变量的命名规则:

长变量以下划线连接,(驼峰型是C#的变量写法)。变量第一个字母小写;Python中没有常量。要打印出变量的内容,除了直接写变量名然后按回车外,还可以用print()函数。

input()print()是在命令行下面最基本的输入和输出,但是,用户也可以通过其他更高级的图形界面完成输入和输出,比如,在网页上的一个文本框输入自己的名字,点击“确定”后在网页上看到输出信息。

五、关于Python的变量赋值

name = “aaaa”
name1 = name
print(name1)

这时打印的name1是aaaa

如果修改name的值,

name = “bbbb”

这时

Print(name1)的结果还是“aaaa”

这里的关键点是name = “aaaa”,先在内存中创建aaaa,然后将这个aaaa的内存地址赋给name变量,而name1 = name是将name所指向的地址赋给了name1,当name=“bbbb”时,是在内存中创建bbbb,然后将bbbb的地址赋给name,而name1依然指向aaaa的地址。使用del 变量名 是手动删除变量。

六、编码部分:

支持中文的第一张表:GB2312

中文编码的发展:GB2312——>BGK1.0——>GB18030

Unicode 万国码,2**16 = 65535    存一个字符,统一占用2个字节

UTF-8  是unicode的扩展集,可变长的字符编码集。Ascii用1个字节保存,欧洲的字节用2个字节,其他国家字符3个字节。

Unicode是向下兼容GBK和GB2312的。

七、注释: #    单行注释

             三个单引号或三个双引号     多行注释

#开头的语句是注释,注释是给人看的,可以是任意内容,解释器会忽略掉注释。其他每一行都是一个语句,当语句以冒号:结尾时,缩进的语句视为代码块。

八、Python书写

缩进:缩进级别必须保持一致

一般四个空格,官方不建议使用tab,在编辑器中可使用将制表符自动换为4个空格。

Python程序是大小写敏感的

九、数据类型和变量

数据类型:

整数:正整数、负整数、零

对于很大的数,例如10000000000,很难数清楚0的个数。Python允许在数字中间以_分隔,因此,写成10_000_000_00010000000000是完全一样的

浮点数:浮点数也就是小数,按照科学记数法表示时,一个浮点数的小数点位置是可变的,比如,1.234X10^{​{9}}和12.34x10^{8}是完全相等的。浮点数可以用数学写法,如1.233.14-9.01,等。但是对于很大或很小的浮点数,就必须用科学计数法表示,把10用e替代,1.234x10^{​{9}}就是1.234e9,或者12.34e8,0.000012可以写成1.2e-5,等等。

整数和浮点数在计算机内部存储的方式不同,整数运算永远是精确的(除法也是精确的!),而浮点数运算则可能会有四舍五入的误差。

字符串:字符串是以单引号'或双引号"括起来的任意文本,比如'abc'"xyz"等。''""本身不是字符串的一部分。如果'本身也是一个字符,那就可以用""括起来,比如"I'm OK"包含的字符是I'm,空格,OK这6个字符。

如果字符串内部既包含'又包含"怎么办?可以用转义字符\来标识,比如:'I\'m \"OK\"!'

表示的字符串内容是:I'm "OK"!

如果字符串里面有很多字符都需要转义,就需要加很多\,为了简化,Python还允许用r''表示''内部的字符串默认不转义

如果字符串内部有很多换行,用\n写在一行里不好阅读,为了简化,Python允许用'''...'''的格式表示多行内容。

上图中的三个点好像理解错了,在保存为文件中的写法如下:

行之间自然回车就行,不需要三个点,上面的显示应该是为了对齐>>>,系统增加的显示符。

布尔值:布尔值和布尔代数的表示完全一致,一个布尔值只有TrueFalse两种值,Python中,可以直接用TrueFalse表示布尔值(请注意大小写),也可以通过布尔运算计算出来。

布尔值可以用andornot运算。

空值:空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值。

变量

变量在程序中就是用一个变量名表示,变量名必须是大小写英文、数字和_的组合,且不能用数字开头。在Python中,等号=是赋值语句,可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量:

这里有一个发现,在交互模式下,使用print()函数打印字符串变量,字符串是没有夹在两个单引号之间的,如果直接打变量名,在显示的结果有两个单引号。

变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。例如Java是静态语言

理解变量在计算机内存中的表示也非常重要:

a = ‘ABC’

时,Python解释器干了两件事情:

  1. 在内存中创建了一个'ABC'的字符串;

  2. 在内存中创建了一个名为a的变量,并把它指向'ABC'

也可以把一个变量a赋值给另一个变量b,这个操作实际上是把变量b指向变量a所指向的数据

执行a = 'ABC',解释器创建了字符串'ABC'和变量a,并把a指向'ABC'

py-var-code-1

执行b = a,解释器创建了变量b,并把b指向a指向的字符串'ABC'

py-var-code-2

执行a = 'XYZ',解释器创建了字符串'XYZ',并把a的指向改为'XYZ',但b并没有更改:

py-var-code-3

所以,最后打印变量b的结果自然是'ABC'了。

常量

所谓常量就是不能变的变量。在Python中,通常用全部大写的变量名表示常量,但事实上PI仍然是一个变量,Python根本没有任何机制保证PI不会被改变,所以,用全部大写的变量名表示常量只是一个习惯上的用法。

编码,在编写程序文件时,第一行一般用:# -*- coding: utf-8 -*-指定编码。

Python支持多种数据类型,在计算机内部,可以把任何数据都看成一个“对象”,而变量就是在程序中用来指向这些数据对象的,对变量赋值就是把数据和变量给关联起来。

inf表示无穷大。

十、字符串和编码

字符编码,关于unicode编码,参见unicode编码详解,简单来说:

  • Unicode 是「字符集」
  • UTF-8 是「编码规则」

其中:

  • 字符集:为每一个「字符」分配一个唯一的 ID(学名为码位 / 码点 / Code Point)
  • 编码规则:将「码位」转换为字节序列的规则(编码/解码 可以理解为 加密/解密 的过程)

广义的 Unicode 是一个标准,定义了一个字符集以及一系列的编码规则,即 Unicode 字符集和 UTF-8、UTF-16、UTF-32 等等编码……

Unicode 字符集为每一个字符分配一个码位,例如「知」的码位是 30693,记作 U+77E5(30693 的十六进制为 0x77E5)。

UTF-8 顾名思义,是一套以 8 位为一个编码单位的可变长编码。会将一个码位编码为 1 到 4 个字节:

U+ 0000 ~ U+  007F: 0XXXXXXX
U+ 0080 ~ U+  07FF: 110XXXXX 10XXXXXX
U+ 0800 ~ U+  FFFF: 1110XXXX 10XXXXXX 10XXXXXX
U+10000 ~ U+10FFFF: 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX

根据上表中的编码规则,之前的「知」字的码位 U+77E5 属于第三行的范围:

       7    7    E    5    
    0111 0111 1110 0101    二进制的 77E5
--------------------------
    0111   011111   100101 二进制的 77E5
1110XXXX 10XXXXXX 10XXXXXX 模版(上表第三行)
11100111 10011111 10100101 代入模版
   E   7    9   F    A   5

这就是将 U+77E5 按照 UTF-8 编码为字节序列 E79FA5 的过程。反之亦然。

现代编码模型
在现代编码模型里要知道一个字符如何映射成计算机里比特,需要经过如下几个步骤:

知道一个系统需要支持哪些字符,这些字符的集合被称为字符表(Character repertoire)
给字符表里的抽象字符编上一个数字,也就是字符集合到一个整数集合的映射。这种映射称为编码字符集(CCS:Coded Character Set), unicode 是属于这一层的概念,unicode 跟计算机里的什么进制啊没有任何关系,它是完全数学的抽象的。
将 CCS 里字符对应的整数转换成有限长度的比特值,便于以后计算机使用一定长度的二进制形式表示该整数。这个对应关系被称为字符编码表(CEF:Character Encoding Form)UTF-8, UTF-16 都属于这层。
对于 CEF 得到的比特值具体如何在计算机中进行存储,传输。因为存在大端小端的问题,这就会跟具体的操作系统相关了。这种解决方案称为字符编码方案(CES:Character Encoding Scheme)。
平常我们所说的编码都在第三步的时候完成了,并没有涉及到 CES。

关于字符集(character set)和编码(encoding),某几篇答案中似乎有些混淆。

对于 ASCII、GB 2312、Big5、GBK、GB 18030 之类的遗留方案来说,基本上一个字符集方案只使用一种编码方案。
比如 ASCII 这部标准本身就直接规定了字符和字符编码的方式,所以既是字符集又是编码方案;而 GB 2312 只是一个区位码形式的字符集标准,不过实际上基本都用 EUC-CN 来编码,所以提及「GB 2312」时也说的是一个字符集和编码连锁的方案;GBK 和 GB 18030 等向后兼容于 GB 2312 的方案也类似。
于是,很多人受这些遗留方案的影响而无法理解字符集和编码的关系。

对于 Unicode,字符集和编码是明确区分的。Unicode/UCS 标准首先是个统一的字符集标准。而 Unicode/UCS 标准同时也定义了几种可选的编码方案,在标准文档中称作「encoding form」,主要包括 UTF-8、UTF-16 和 UTF-32。
所以,对 Unicode 方案来说,同样的基于 Unicode 字符集的文本可以用多种编码来存储、传输。
所以,用「Unicode」来称呼一个编码方案不合适,并且误导。

[1] Windows 里说的「ANSI」其实是 Windows code pages,这个模式根据当前 locale 选定具体的编码,比如简中 locale 下是 GBK。把自己这些 code page 称作「ANSI」是 Windows 的 臭毛病。在 ASCII 范围内它们应该是和 ASCII 一致的。
[2] 把带有 BOM 的小端序 UTF-16 称作「Unicode」也是 Windows 的 臭毛病。Windows 从 Windows 2000 开始就已经支持 surrogate pair 了,所以已经是 UTF-16 了,「UCS-2」这个说法已经不合适了。UCS-2 只能编码 BMP 范围内的字符,从 1996 年起就在 Unicode/ISO 标准中被 UTF-16 取代了(UTF-16 通过蛋疼的 surrogate pair 来编码超出 BMP 的字符)。都十多年了,求求大家别再误称了……
[3] 把带 BOM 的 UTF-8 称作「UTF-8」又是 Windows 的 臭毛病。如果忽略 BOM,那么在 ASCII 范围内与 ASCII 一致

Python的字符串

在最新的Python 3版本中,字符串是以Unicode编码的,也就是说,Python的字符串支持多语言。这里,个人感觉不能说Unicode编码,应该说Unicode码点,即字符串是以Unicode的码点保存的。这里还是有疑惑的,因为Unicode的码点范围是从0~10FFFF,超过FFFF的码点怎么表示?现在看到的网上资料基本上举例都是\u1e45这种样子,没有超过两个字节的,Unicode码点有100多万个,现在使用的有13万多个,分成17个平面,13万用二进制表示,也是超过两个字节了,怎么表示?

对于单个字符的编码,Python提供了ord()函数获取字符的整数表示(就是Unicode码点),chr()函数把编码转换为对应的字符。

关于Python的字符串以及编码,看这里吧——Python中的字符串与字符编码

字符集、编码等的知识还是很复杂的,慢慢积累吧。

十一、格式化

如何输出格式化的字符串。在Python中,采用的格式化方式和C语言是一致的,用%实现

%运算符就是用来格式化字符串的。在字符串内部,%s表示用字符串替换,%d表示用整数替换,有几个%?占位符,后面就跟几个变量或者值,顺序要对应好。如果只有一个%?,括号可以省略。变量的使用与C不同,需要一个%再加变量列表,多于一个变量,需要使用括号。

常见的占位符有:

占位符替换内容
%d整数
%f浮点数
%s字符串
%x十六进制整数

 

 

 

 

 

 

其中,格式化整数和浮点数还可以指定是否补0和整数与小数的位数:

些时候,字符串里面的%是一个普通字符怎么办?这个时候就需要转义,用%%来表示一个%

format()

另一种格式化字符串的方法是使用字符串的format()方法,它会用传入的参数依次替换字符串内的占位符{0}{1}……,

f-string

最后一种格式化字符串的方法是使用以f开头的字符串,称之为f-string,它和普通字符串不同之处在于,字符串如果包含{xxx},就会以对应的变量替换

 

  • 12
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值