Python基础篇

Python简介


Python ,是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum于1989年发明,第一个公开发行版发行于1991年。

 解释器执行原理


Python在执行时,首先会将.py文件中的源代码编译成Python的字节码,然后再由Python虚拟机来执行这些编译好的字节码。这种机制的基本思想跟Java,.NET是一致的。然而,Python虚拟机与Java或.NET的虚拟机不同的是,Python的虚拟机是一种更高级的虚拟机。这里的高级并不是通常意义上的高级,不是说Python的虚拟机比Java或.NET的功能更强大,而是说和Java 或.NET相比,Python的虚拟机距离真实机器的距离更远。或者可以这么说,Python的虚拟机是一种抽象层次更高的虚拟机。基于C的Python编译出的字节码文件,通常是.pyc格式。

 

字符编码/注释/变量/缩进


字符编码:Unicode固然统一了编码方式,但是它的效率不高,比如UCS-4(Unicode的标准之一)规定用4个字节存储一个符号,那么每个英文字母前都必然有三个字节是0,这对存储和传输来说都很耗资源。为了提高Unicode的编码效率,于是就出现了UTF-8编码。UTF-8可以根据不同的符号自动选择编码的长短。比如英文字母可以只用1个字节就够了。在python文件中,如果有中文,就一定要在文件的第一行标记使用的编码类型,例如 #-*-encoding=utf-8-*- ,就是使用utf-8的编码。

注释:#

变量:计算机语言中能储存计算结果或能表示值抽象概念。变量可以通过变量名访问。

在机器的内存中,系统分配一个空间,这里面就放着所谓的对象,有时候放数字,有时候放字符串。如果放数字,就是int类型,如果放字符串,就是str类型。接下来的事情,就是变量用自己所拥有的能力,把对象和自己连接起来(指针连接对象空间),这就是引用。引用完成,就实现了赋值。

缩进:对于Python而言代码缩进是一种语法,Python没有像其他语言一样采用{}或者begin...end分隔代码块,而是采用代码缩进和冒号来区分代码之间的层次。缩进的空白数量是可变的,但是所有代码块语句必须包含相同的缩进空白数量,这个必须严格执行。

流程控制:


if语句、for语句、range函数、breakcontinue 语句,循环时使用elsepass语句

1 if 语句
>>> x = int(input("Please input a number: "))
Please input a number: 3
>>> x 
3
>>> if x < 0:
...      x = 0
...      print'Negative number')
... elif x == 0:
...      print ('Zero')
... elif x == 1:
...      print ('Single')
... else:
...      print ('More')
... 
More

2 for 语句
Python 中的 for 语句和 C 或者 Pascal 中的for语句有所不同,在c中,for 语句通常由 判断语句,条件判断,值变化 三部分 构成,python 中 for 语句结构是在一个序列上遍历:

>>> # Measure some string
... words = ['cat', 'windows', 'linux']
>>> for w in words:
...     print (w, len(w))
... 
cat 3
windows 7
linux 5

3 range函数
如果你想在一个数字序列上迭代,那么range函数可能对你有用,从下面的例子中体会range 的不同表达式的含义:

>>> range (5)
[0, 1, 2, 3, 4]
>>> range (2,5)
[2, 3, 4]
>>> range (5,10,1)
[5, 6, 7, 8, 9]
>>> range (5,10,2)
[5, 7, 9]
>>> range (5,10,3)
[5, 8]

如果想使用下标在一个序列上迭代,可以使用range函数

>>> words
['cat', 'windows', 'linux']
>>> for i in range(len(words)):
...     print (i, words[i])
... 
0 cat
1 windows
2 linux

多数情况下,enumerate函数会更方便。我们在后面的章节会介绍。
4 breakcontinue 语句,循环时使用else braak:直接跳出整个循环,continue:停止本次循环,直接开始下一次的循环 else可以用于for循环,当循环自然终止,即没有被break中止时,会执行else下的语句 >>> for n in range (2,10): ... for x in range (2,n): ... if n % x == 0: ... print (n, 'equals', x, '*', n/x) ... break ... else: ... print (n, 'is a prime number') ... 2 is a prime number 3 is a prime number 4 equals 2 * 2 5 is a prime number 6 equals 2 * 3 7 is a prime number 8 equals 2 * 4 9 equals 3 * 3 continue语句,从C语言中借鉴而来,直接转入循环的下一次迭代。 >>> for num in range(2,10): ... if num % 2 == 0: ... print (num, 'is an even number') ... continue ... print (num, 'is not an even number') ... 2 is an even number 3 is not an even number 4 is an even number 5 is not an even number 6 is an even number 7 is not an even number 8 is an even number 9 is not an even number 5 pass语句 pass 语句什么都不做,用于需要一个语句以符合语法,但又什么都不需要做时, 也可以用于写一个空函数 >>> while True: ... pass #busy-wait for keyboard interrupt (Ctrl+c) ... ^CTraceback (most recent call last): File "<stdin>", line 1, in <module> KeyboardInterrupt >>> class myEmptyClass: ... pass ... >>> def initlog(*args): ... pass # Remember to implement this ...

 

初识文件操作

读取文件内容

#
要以一个读的模式打开一个文件,使用open()函数,r 表示以read的模式打开 f = open('test.text','r') #使用read()可以一次性读取文件的全部内容,python把内容读到内存,用一个str表示 print(f.read()) #使用close关闭文件,文件使用完毕后必须关闭,不让文件对象会占用操作系统的资源 f.close()
写内容进文件

#创建一个新文件,w 表示以wirte的模式创建一个新文件
f = open('NewFile.text','w')
#往创建的文件里面写东西
f.write('This is frist line!!!
')
f.write('This is second line!!!
')
#关闭文件
f.close()
追加文件内容

#以追加的模式打开文件
f = open('test.text','a')
#往文件里写东西
f.write('this line is append!!!!
')
f.close()
修改文件的内容

#打开文件
f = open('test.text','r')
new_f = open('new_test.text','w')
for line in f:
    if 'old' in line:#判断需要修改的内容是否在这一行
        line = line.replace(line,'---new---
')#替换
    new_f.write(line)#往新建的文件里写东西
f.close()
new_f.close()
f = open('test.text','r')
print(f.mode) # f.mode 显示文件打开的格式
f.close()

f = open('test.text','r')
print(f.read())#f.read把文件一次性读到内存
f.close()

f = open('test.text','r')
print(f.readline())#f.readline读第一行到内存
print(f.readline())#f.readline读第二行到内存
print(f.readline())#f.readline读第三行到内存
f.close()

f = open('test.text','r')
print(f.readlines()) #把文件都读到内存,并且每行转换成列表中的一个元素
f.close()

f.tell()#显示程序光标所在该文件中的当前位置
f.seek(0)#跳到指定位置,0即表示文件开始位置

f = open('test.text','r+')
f.truncate(4)#从文件开头截取4个字节,超出的都删除
f.close()

li = ['one','two','three','four']
f = open('test.text','r+')
f.writelines(li)#参数需为一个列表,将列表中的每个元素都写入文件
f.close()

f.xreadlines()#以迭代的形式循环文件,在处理大文件是极为有效,只记录文件开头和结尾,每循环一次,只读取一行,因此不需要一次性把文件加载到内存,而使用readlines()则需要把文件全部加载到内存中


数据类型内置方法


number1 = 123  #整数
number2 = 'abc'  #字符串
number3 = [1,2,3]  #列表
number4 =(1,2,3)  #元组
number5 = {1:'a',2:'b'}  #字典
print(type(number1))
print(type(number2))
print(type(number3))
print(type(number4))
print(type(number5))





<class 'int'>
<class 'str'>
<class 'list'>
<class 'tuple'>
<class 'dict'>

 

字符串格式化


字符串格式化符号
格式化符号说明
%c 转换成字符(ASCII 码值,或者长度为一的字符串)
%r 优先用repr()函数进行字符串转换(Python2.0新增)
%s 优先用str()函数进行字符串转换
%d / %i  转成有符号十进制数
%u 转成无符号十进制数
%o 转成无符号八进制数
%x / %X (Unsigned)转成无符号十六进制数(x / X 代表转换后的十六进制字符的大
小写)
%e / %E 转成科学计数法(e / E控制输出e / E)
%f / %F 转成浮点数(小数部分自然截断)
%g / %G %e和%f / %E和%F 的简写
%% 输出%

 当然,还有一些辅助符号,如下表所示:

辅助符号 说明
* 定义宽度或者小数点精度
- 用做左对齐
+ 在正数前面显示加号(+)
<sp> 在正数前面显示空格
# 在八进制数前面显示零(0),在十六进制前面显示“0x”或者“0X”(取决于用的是“x”还是“X”)
0 显示的数字前面填充“0”而不是默认的空格
m.n m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话)

 注意:辅助符号要在百分号(%)和格式化符号之间。

charA = 65
charB = 66
print("ASCII码65代表:%c" % charA)
print("ASCII码66代表:%c" % charB)
Num1 = 0xFFFF
Num2 = 0xFFFFFFFFFFFFFFFF
print('转换成十进制分别为:%u和%u' % (Num1, Num2))

Num3 = 1200000
print('转换成科学计数法为:%e' % Num3)
Num4 = 108
print("%#X" % Num4)
Num5 = 234.567890
print("%.4f" % Num5)

运算符


按你的理解去理解

输入输出


str = input("请输入:");
print ("你输入的内容是: ", str)

三元运算


python没有三元运算符,代替方案

num = -10
print("正数") if num > 0 else print("负数")#先判断if后面的条件,满足条件执行if前面的语句,不满足则执行else后面的语句

 collections模块


我们都知道,Python拥有一些内置的数据类型,比如str, int, list, tuple, dict等, collections模块在这些内置数据类型的基础上,提供了几个额外的数据类型:

  • namedtuple(): 生成可以使用名字来访问元素内容的tuple子类
  • deque: 双端队列,可以快速的从另外一侧追加和推出对象
  • Counter: 计数器,主要用来计数
  • OrderedDict: 有序字典
  • defaultdict: 带有默认值的字典

 列表、字典、元组、集合


 列表:列表可以当成普通的数组,每当用到引用时,Python总是会将这个引用指向一个对象,所以程序只需处理对象的操作。当把一个对象赋给一个数据结构元素或变量名时,Python总是会存储对象的引用,而不是对象的一个拷贝。list的官方内置函数可用dir(list)help(list) 命令进行查看。

L = ['qypt','ctc']  #创建列表
li = [1,2,3,4,['a','b','c'],'abc','abc','a','a','a',9,5]    #创建列表
print(
    li[1],'
',         #list的索引,左1索引为0,右1索引为-1
    li[1:5:2],'
',      #list的切片,切一部分,范围为索引[1,5),即1、2、3、4不包括5,隔2取1个值
    li[4][1],'
',       #列表支持嵌套
    li.append('append_number'),'
',   #追加元素,加在最后
    li.insert(1,'index_num') ,'
',    #在index的位置追加元素,位置就是索引
    li.pop(),'
',                #从list中删除最后一个元素,并返回该元素
    li.remove('a'),'
',            #删除第一次出现的该元素
    li.count('a'),'
',                #该元素在列表中出现的个数
    li.index(4),'
',                  #该元素的位置(索引号),无则抛异常
    #li.sort(),'
',                   #排序,列表元素需为int类型
    li.extend(L),'
',                 #追加list,即合并L到li上,两个列表合并
    li.reverse()                       #原地翻转列表,从前到后变成从后向前
    )
print(li)

----------------------------------------------------------------------------------------------------------->
运行结果:
2 [2, 4] b None None append_number None 2 4 None None ['ctc', 'qypt', 5, 9, 'a', 'a', 'abc', 'abc', ['a', 'b', 'c'], 4, 3, 2, 'index_num', 1]

字典:字典就是一个关联数组,是一个通过关键字索引的对象的集合,使用键-值(key-value)进行存储,查找速度快,嵌套可以包含列表和其他的字典等,因为是无序,故不能进行序列操作,但可以在远处修改,通过键映射到值。字典是唯一内置的映射类型(键映射到值的对象)。字典存储的是对象引用,不是拷贝,和列表一样。字典的key是不能变的,list不能作为key,字符串、元祖、整数等都可以。

d = {'Name':'ctc','Addr':'qypt','Tel':'130***6'}     # 创建dict
print(d['Name'])     # 找出key为Name的值 d['Name'] == 'ctc'
d['Name'] = 'chentaicheng'  # 更新key为Name的值 Name对应的值从ctc改为chentaicheng
print(d['Name'])     # 找出key为Name的值 d['Name'] == 'chentaicheng'
del d['Name']       # 删除key为Name的值和该key d = {'Name': 'chentaicheng'}
d.clear()           #删除字典d中的所有元素 d = {}
d.pop('Addr')       #删除字典d中key为'Addr'的值和该键
d.copy()                    # 返回字典d的浅复制副本

seq = ('name','addr','tel')
dict = d.fromkeys(seq,10)   # 创建一个新的字典,设置键为seq 和值为value
print(dict)

D = d.get('Name')      #返回该键key的值
D = d.items()                      # 返回字典的(键,值)元组对的列表
D =d.keys()                       # 返回字典的键的列表
D = d.values()                     # 返回字典d的值列表
print(D)
d.iteritems()                  # (键,值)项的一个迭代器
d.iterkeys()                   # 字典d中键的一个迭代器
d.itervalues()                 # 字典d中值的一个迭代器
d.viewitems()                 # 像对象一样提供字典d中项的一个视图
d.viewkeys()                   # 像对象一样提供字典d中key的一个视图
d.viewvalues()                 # 像对象一样提供字典d中value的一个视图

元组:有序集合,通过偏移存取,属于不可变序列类型.固定长度、异构、任意嵌套,与列表相似,元祖是对象引用的数组。

和list相比
1.比列表操作速度快
2.对数据“写保护“
3.可用于字符串格式化中
4.可作为字典的key

 t.count(var)               # 该元素在元组中出现的个数
 t.index(var)               # 该元素的位置(索引号),无则抛异常

集合:set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作。还有一种集合是forzenset( ),是冻结的集合,它是不可变的,存在哈希值,好处是它可以作为字典的key,也可以作为其它集合的元素。缺点是一旦创建便不能更改,没有add,remove方法。

s = set([1,2,3])            # 创建一个数值set,有1,2,3三个元素s == set([1, 2, 3])
se = set('Hello')           # 创建一个唯一字符的集合s == set(['H', 'e', 'l', 'o'])
a = s | se                  # s 和 se 的并集 set([1, 2, 3, 'e', 'H', 'l', 'o'])
b = s & se                  # s 和 se 的交集 set([]) 没有相同项为空
c = s - se                 # 求差集(项在s中,但不在se中) set([1, 2, 3])
d = s ^ se                  # 对称差集(项在s或se中,但不会同时出现在二者中)
                            
print(s)
print(se)
print(a)
print(b)
print(c)
print(d)
------------------------------------------------------------------------------------------->
------------------------------------------------------------------------------------------->
运行结果
{1, 2, 3}
{'H', 'l', 'o', 'e'}
{'o', 1, 2, 3, 'H', 'l', 'e'}
set()
{1, 2, 3}
{'o', 1, 2, 3, 'H', 'l', 'e'}
************************************************************************
li = [4,5,6]
s = set([10,10,1,2,3,4,5,5,6,6,5,7,9,7,7,7,7,7,7])
t = set([20,10,1,2,3])
print(s.issubset(t))              # 如果s是t的子集,则返回True,否则返回False
print(s.issuperset(t))             # 如果t是s的超集,则返回True,否则返回False
print(s.union(t))                  # 返回一个新集合,该集合是s和t的并集
print(s.intersection(t))           # 返回一个新集合,该集合是s和t的交集
print(s.difference(t))             # 返回一个新集合,该集合是 s 的成员,但不是 t 的成员
print(s.symmetric_difference(t))   # 返回一个新集合,该集合是s或t的成员,但不是s和t共有的成员
print(s.copy())                    # 返回一个新集合,它是集合s的浅复制

print(s.pop()) # 删除集合是中的任意一个对象,并返回它

s.update(t) # 用t中的元素修改s,即s现在包含s或t的成员 s.intersection_update(t) # s中的成员是共同属于s和t中的元素 s.difference_update(t) # s中的成员是属于s但不包含在t中的元素 s.symmetric_difference_update(t) # s中的成员更新为那些包含在s或t中,但不是s和t共有的元素 s.add(100) # 在集合s中添加对象obj s.remove(2)# 从集合s中删除对象obj,如果obj不是集合s中的元素,(obj not in s),将引发KeyError s.discard(2) # 如果obj是集合s中的元素,从集合s中删除对象obj s.clear() # 删除集合s中的所有元素



函数: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可


特性:

  1. 减少重复代码
  2. 使程序变的可扩展
  3. 使程序变得易维护
语法定义
def sayhi():#函数名
    print("Hello, I'm kuangluxuanzhadiaofantian!")
 
sayhi() #调用函数
可以带参数
#下面这段代码
a,b = 5,8
c = a**b
print(c)
 

#改成用函数写
def calc(x,y):
    res = x**y
    return res #返回函数执行结果
 
c = calc(a,b) #结果赋值给c变量
print(c)
 

形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量

实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值

默认参数

看下面代码
def stu_register(name, age, country, course):
    print("----注册学生信息------")
    print("姓名:", name)
    print("age:", age)
    print("国籍:", country)
    print("课程:", course)

stu_register("王山炮", 22, "CN", "python_devops")
stu_register("张叫春", 21, "CN", "linux")
stu_register("刘老根", 25, "CN", "linux")

发现country这个参数基本都是
"CN", 就像我们在网站上注册用户,像国籍这种信息,你不填写,默认就会是中国, 这就是通过默认参数实现的,把country变成默认参数非常简单 def stu_register(name, age, course, country="CN"): 这样,这个参数在调用时不指定,那默认就是CN,指定了的话,就用你指定的值。另外,你可能注意到了,在把country变成默认参数后,我同时把它的位置移到了最后面,为什么呢?   关键参数 正常情况下,给函数传参数要按顺序,不想按顺序就可以用关键参数,只需指定参数名即可,但记住一个要求就是,关键参数必须放在位置参数之后。 stu_register(age=22, name='alex', course="python", )
非固定参数
若你的函数在定义时不确定用户想传入多少个参数,就可以使用非固定参数
def stu_register(name,age,*args): # *args 会把多传入的参数变成一个元组形式
    print(name,age,args)

stu_register('ctc',22) #输出 ctc 22 (),后面这个()就是args,只是因为没传值,所以为空
stu_register('ctc',22,'python','qypt') #输出 ctc 22 ('python', 'qypt')

还可以有一个**kwargs
def stu_register(name,age,*args,**kwargs): # *kwargs 会把多传入的参数变成一个dict形式
    print(name,age,args,kwargs)

stu_register('ctc',22) #输出ctc 22 () {},{}#后面这个{}就是kwargs,只是因为没传值,所以为空
stu_register('ctc',22,'python','qypt') #输出 ctc 22 ('python', 'qypt') {}
stu_register('ctc',22,'python',school = 'qypt',sex = 'man') #ctc 22 ('python',) {'school': 'qypt', 'sex': 'man'}
'''
全局与局部变量
在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
'''
name = "ChenTaicheng"  #全局变量


def change_name(name):
    print("before change:", name)
    name = "一个改变世界的人"  #局部变量
    print("after change", name)


change_name(name)

print("在外面看看name改了么?", name) 

返回值

要想获取函数的执行结果,就可以用return语句把结果返回

注意:

  1. 函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return 语句代表着函数的结束
  2. 如果未在函数中指定return,那这个函数的返回值为None
递归

在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
def calc(n):
    print(n)
    if int(n / 2) == 0:
        return n
    return calc(int(n / 2))


f = calc(10)
print(f)

输出:
10
5
2
1
1

递归特性:

1. 必须有一个明确的结束条件

2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少

3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

匿名函数 :匿名函数就是不需要显式的指定函数

#这段代码
def calc(n):
    return n**n
print(calc(10))
 
#换成匿名函数
calc = lambda n:n**n
print(calc(10))
你也许会说,用上这个东西没感觉有毛方便呀, 。。。。呵呵,如果是这么用,确实没毛线改进,不过匿名函数主要是和其它函数搭配使用的呢,如下
res = map(lambda x:x**2,[1,5,7,4,8])
for i in res:
    print(i)
输出
1
25
49
16
64

高阶函数:变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

 

内置参数:



面向对象


对象是对客观事物的抽象,类是对对象的抽象。
类是一种抽象的数据类型,它们的关系是,对象是类的实例,类是对象的模板。
函数与类:
def func():
    print('hello,world!')
    return '返回值'    #默认为 None
 
#调用函数
r = func()
print(r)

class Foo:      #class 类名
 
    def F1(self,name):   #定义函数,在类中叫做方法
        print('Hello,world!')
        print(name)
        return '返回值'
 
#调用类
#创建对象
obj = Foo()     #对象 = 类名()
#通过对象执行方法
r = obj.F1('chentaicheng')  #对象.方法()
print(r)

原文地址:https://www.cnblogs.com/tcheng/p/5876175.html