Python入门-再读《Python编程:入门到实践》
《Python 编程:从入门到实践》
二、变量和简单数据类型
运行.py时发生的事情
Python解释器读取整个程序,确定其中每个单词的含义。看到单词print时,解释器就会将括号中的内容打印到屏幕,而不会管括号中的内容是什么。
变量
- 变量名只能包含字母、数字和下划线。变量名可以字母或下划线打头,但不能以数字打头。
- 变量名不能包含空格,但可使用下划线来分隔其中的单词。
- 不要将Python关键字和函数名用作变量名。
当程序无法成功运行时,解释器会提供一个traceback。traceback是一条记录,指出了解释器尝试运行代码时,在什么地方陷入了困境。
字符串
Python中用引号括起的都是字符串,其中引号可以是单引号,也可以是双引号。
这种灵活性能够让我们在字符串中包含引号和撇号
"This is a string."
'This is also a string.'
'I told my friend, "Python is my favorite language!"'
一些函数
-
title() 让每个单词的第一个字母大写
-
upper() 让所有字符大写
-
lower() 让所有字符小写
-
可以使用+进行字符串拼接
- 在使用数字拼接时,要使用str()函数将其转换为字符再拼接
-
\t 制表 \n换行 \n\t换行并制表
-
strip()去除头尾空格,lstrip()去除头空格,rstrip()去除尾空格
单引号引起的语法错误
#true
message = "One of Python's strengths is its diverse community"
print(message)
#false
message = 'One of Python's strengths is its diverse community'
print(message)
数字
print(2 + 3)
print(2 * 3)
print(2 - 3)
print(2 / 3)
#整除
print(2 // 3)
#乘方
print(2 ** 3)
三、列表
列表由一系列按特定顺序排列的元素组成,可以将不同类型的数据放入列表。
创建列表
列表用方括号来表示,用逗号来分隔其中的元素。
list1 = ['111', 'aaa', 'bbb']
print(list1) // ['111', 'aaa', 'bbb']
操作列表元素
可以根据下表访问、修改列表元素。
python支持-1访问最后一个元素,-2指定倒数第二个元素,以此类推。
#列表末尾添加元素
list1.append('ccc')
#列表插入元素,右侧元素右移
list1.insert(index, 'ddd')
#删除元素
del list1[0]
#越界报错
pop = list1.pop()
pop1 = list1.pop(2)
#根据值删除,没有值会报错,只会删第一个值
list1.remove('aaa')
组织列表
#永久排序
list1 = ['aaa','111','bbb']
list1.sort() //默认升序排列
list1.sort(reverse=True)//降序排列
#如果列表中元素不可比较,会报错
#临时排序
list2 = sorted(list1)
list3 = sorted(list1, reverse=True)
#反转顺序,没有返回值,不能赋给另一个列表
list1.reverse()
#获取长度,如果列表为None,则报错
len(list1)
遍历列表
list1 = ['aaa','111','bbb']
for i in list1:
print(i)
#由换行严格限制循环体范围
#for之后没有缩进,即没有循环体会报错
#不允许无效缩进,会报错
#冒号表示,下一行是循环的第一行,没冒号报错
range 创建数值列表
for value in range(1, 5):
print(value)
#1 ~ 4 打印
#list()将range结果转化为列表
list2 = list(range(1,6))#1,2,3,4,5
list2 = list(range(1, 5, 2))#指定步长 1,3
list2 = list(range(7, 1, -2))#7, 5, 3
#简单聚合分析
a = min(list2)
b = max(list2)
c = sum(list2)
#列表解析
list3 = [value ** 2 for value in range(1,11)]
列表切片
list1 = ['aaa','111','bbb']
list2 = list1[0: 1] #aaa
list3 = list1[0: -1] #aaa, 111
#复制列表
list2 = list1 # 浅拷贝
list2 = list1[:] # 深拷贝
元组
不可变的列表 -> 元组
dims = (100, 20)
#修改元组元素会报错
for dim in dims:
print(dim)
#元组不可修改,可以修改引用
dims = (200,30)
四、if
#检查是否相等
a = 1
if a == 1: print('equal')
if a != 2: print('not equal')
#多条件
and #与
or #或
#范围查找
list1 = ['aaa','111','bbb']
user = 'bbb'
if user in list1: print('in')
if user not in list1: print("not in")
if a == 1: print('aaa')
else: print('bbb')
if a == 1: print('aaa')
elif b == 1: print('bbb')
else: print('ccc')
列表是否为空
list1 = []
#if list1: #为false
list2 = None
#if list2: #为false
#但是list1仍是list,可以append,list2不支持append
五、字典
字典是一些列键值对
- 键可以为None,值也可以为None
- 键冲突时,输出后面的
- 列表无法作为键,unhashable
- 可以用dict['aaa']来访问、修改对应的值
- 可以dict['bbb'] = 2来添加键值对
- 使用del dict['aaa']来删除键值对
- 最后一个元素可以多一个逗号
遍历
dict1 = {
'username': 'aaa',
'first': 'Alice',
'last': 'Bob'
}
for key, value in dict1.items():
print(key)
print(value)
for key in dict1.keys():
print(key)
for value in dict1.values():
print(value)
#利用set方法去重
for value in set(dict1.values()):
print(value)
嵌套
- 允许嵌套,value可以为dict,可以为list,可以为dict
六、输入
input()
#input接受屏幕输入,可以传入提示信息
age_str = input("input your age\n")
age = int(age_str)
print(age >= 18)
#得到的是字符串,可以用int()将结果parse为Int,再进行比较
七、while
- 通过条件控制
- break
- continue
cn = 0
while cn < 10:
cn += 1
#python不支持++
list1 = ['aaa','111','bbb']
list2 = []
while list1:
list2.append(list1.pop())
list1 = ['aaa', '111', 'bbb', 'aaa']
while 'aaa' in list1:
list1.remove('aaa')
八、函数
使用关键字def定义一个函数
def get_name():
参数
-
位置实参,参数位置和形参位置相同
-
关键词实参,通过指定关键字,来改变实参位置。
- def describe_pet(animal_type, pet_name):
- describe_pet(animal_type='hamster', pet_name='harry')
-
默认值,形参可以指定默认值,传参时不传就使用默认值
- def describe_pet(pet_name, animal_type='dog')
-
传递任意数量的实参(可变形参)
- def make_pizza(*toppings):
- 可输入任意多个参数。
- 形参名*toppings中的星号让Python创建一个空元组,并将收到的所有值都封装到这个元组中
-
结合位置实参与任意数量实参
- def make_pizza(size, *toppings):
- 调用时按顺序调用即可。
-
结合关键字实参与任意数量实参
-
需要接受任意数量的实参,但预先不知道传递给函数的会是什么信息。可将函数编程写能够接受任意数量的键值对
-
def build_profile(first, last, **user_info):
-
build_profile('albert', 'einstein',location='priceton', field='physics')
-
传递参数
- 基本类型:只传递副本,不更改原值
- list、dict:传递引用,会更改原引用指向的对象。
导入模块
要让函数是可导入的,得先创建模块。
模块是扩展名为.py的文件
- 导入整个模块
- import pizza
- 需要用pizza.make_pizza调用
- 导入特定函数
- from module_name import function_name
- 直接调用
- 导入多个函数
- from module_name import function_a, function_b
- 直接调用
- 使用as给函数指定别名
- from pizza import make_pizza as mp
- 使用as给模块指定别名
- import pizza as p
- 导入模块中的所有函数
- from pizza import *
- 不推荐使用,每个函数都可以直接用函数名调用。容易混淆。如果模块中的函数名称有相同的,可能导致意想不到的结果。
函数编写建议
- 函数指定描述性名称
- 只使用小写字母和下划线。
九、类
class Dog():
def __init__(selfm name, age):
"""初始化属性name和age"""
self.name = name
self.age = age
def sit(self):
print(self.name.title() + "is now sitting.")
def roll_over(self):
print(self.name.title() + " rolled over!")
__init__(self, name, age)
构造方法,当创建Dog对象时自动调用。self相当于Java中的this指针。
在传参时不需要传入self,但是必须作为形参写入。
开头末尾的两个下划线是约定,避免Python默认方法与普通方法发生名称冲突。
以self为前缀的变量都可供类中的所有方法使用,可以通过类的任何实例来访问这些变量。
创建实例
my_dog = Dog('willie', 6)
大写的是类,小写的是实例
属性指定默认值
class Car():
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
修改属性值
- 直接修改
- 通过方法修改
- def update_odometer(self, mileage):
- self.odometer_reading = mileage
继承
一个类继承另一个类时,自动获得另一个类的所有属性和方法。
创建子类时,父类必须包含在当前文件夹,且位于子类前面。
__init__()
创建子类实例时,Python首先需要给父类的所有属性赋值。
class Car():
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
class ElectricCar(Car):
def __init__(self, make, model, year):
super().__init__(make, model, year)
重写
重写的方法与父类方法同名
将实例作为属性
类似于Java的接口,又有点不像。
将类的一部分作为一个独立的类提取出来。将大类拆分成多个协同工作的小类。
class Car():
--snip--
class Battery():
def __init__(self, battery_size=70):
selef.batttery_size = battery_size
def describe_battery(self):
print("This car has a " + str(self.battery_size) + "-kWh battery.")
class ElectricCar(Car):
def __init__(self, make, model, year):
super().__init__(make, model, year)
self.battery = Battery()
导入类
同一个.py文件中如有多个同名类,后面的将覆盖前面的类
- 导入单个类
- from car import Car
- 直接创建Car即可
- 从一个模块中导入多个类
- from car import Car, ElectircCar
- 导入整个模块
- import car
- 通过模块名.类名的方式访问
- 导入模块中的所有类
- from module_name import *
- 不推荐使用,这种方式不明确,还会导致名称困惑
- 在一个模块中导入另一个模块
- 一个模块需要其他模块
类编写建议
- 类名采用驼峰命名法,每个单词首字母大写,不使用下划线
- 实例名和模块名都小写,并在单词间加下划线。
- 在类中用一个空行来分隔方法,在模块中用两个空行来分隔类。
十、文件
#读取整个文件
with open(filename, 'mode') as file_obj:
contents = file_obj.read()
with open(filename, 'mode') as file_obj:
contents = file_obj.readlines()
with open(filename, 'mode') as file_obj:
contents = file_obj.readlines()
#with会自动在合适的时机关闭文件。
#可用open() close()替代,但时机需要额外的考虑
#读取文件前后可能有无用的换行符、空格,可用strip()等方法去除。
#mode 'w'只读, 'r' 只写, 'a' append追加写, 'r+' 读写模式
#写时没有某个文件会自动创建,w会覆盖,a会追加
#python只能写入字符串,数字要通过str()转换
JSON
使用json模块,可以操作json数据
import json
nums = [1,2,3,4,5]
filename = 'a.json'
with open(filename, 'w') as f_obj:
json.dump(nums, f_obj)
with open(filename) as f_obj1:
list1 = json.load(f_obj1)
十一、异常
#使用try-except-else来处理异常
try:
print(5 / 0)
except ZeroDivisionError:
print("You cannot divide by zero")
else:
print("sth")
#try块成功运行时,会走else代码块
#FileNotFoundError
#split()方法会拆分文本,并返回一个列表
#这个split更高级,多个空格时会省略空字符串
#当发生错误时,什么事也不做,pass关键字
try:
--snip--
except FileNotFoundError:
pass
else:
--snip
在重构代码时,尽量让函数有返回值,可以根据返回值来方便测试
十二、测试
Python标准库的模块
unittest提供了代码测试工具。
- 单元测试:用于核实函数的某个方面没有问题
- 测试用例:一组单元测试
- 良好的测试用例考虑了函数可能收到的各种输入
- 全覆盖测试
- 一整套单元测试,涵盖了各种可能的函数使用方式。
- 对于大型项目,实现全覆盖很难
起手式
import unittest
from name_function import get_formatted_name
class NamesTestCase(unittest.TestCase):
def test_first_last_name(self):
formatted_name = get_formatted_name('janis', 'joplin')
self.assertEqual(formatted_name, 'Janis Joplin')
unittest.main()
- 继承unittest类
- 测试方式test打头,这样才会在运行.py时自动运行
- 使用断言assert判断是否符合预期
测试类
| 方法 | 用途 |
|---|---|
| assertEqual(a, b) | 核实 a == b |
| assertNotEqual(a, b) | 核实 a != b |
| assertTrue(x) | 核实 x为True |
| assertFalse(x) | 核实 x为False |
| assertIn(item, list) | 核实 item在list中 |
| assertNotIn(item, list) | 核实 item不在list中 |
setUp()方法
每个测试方法都创还能了一个对象实例。
unittest.TestCase类包含了setUp()方法,可以只创建一次对象,并在每个测试方法中使用。
import unittest
from survey import AnonyousSurvey
class TestAnonymousSurvey(unittest.TestCase):
def setUp(self):
"""创建一个调查对象和一组答案,供使用的测试方法使用"""
question = "What language did you first learn to speak?"
self.my_survey = AnonymousSurver(question)
self.responses = ['English', 'Spanish']
浙公网安备 33010602011771号