《python编程从入门到实践》第二版---读书笔记-——第一部分

本文旨在记录读书过程中感兴趣,用得上的部分,不会过与详尽。

源代码:

ehmatthes/pcc_2e: Online resources for Python Crash Course (Second Edition), from No Starch Press (github.com)

---------------------------------------------------------------------------------------------------------------------------------

作者建议:①第一部分在42小时内快速浏览一遍,不用理解,混个眼熟。

                  ②第二部分跟着项目实践精读,对应查阅第一部分的基础知识点,针对性地自我答疑。

                        只记录第一部分的内容。

第一部分 基础知识(1~11章)

第一章 起步

1、Windows

        检查你的系统是否安装了python:在cmd里面打出'python'

        关闭终端会话:按Ctrl+Z,再按回车,或执行命令exit()

2、Linux

        用Ctrl+Alt+T 打开终端,打出'python3'

        关闭终端:Ctrl+D exit()

         将windows中每个命令python都替换为python3      

3、 编写第一个程序

        编写第一个程序前,在系统中创建一个名为python_work的文件夹,用于存储项目。

       文件名和文件夹名称最好使用小写字母,并使用下划线代替空格。

4、命令窗口

在命令窗口中    cd    切换目录

                                dir    windows下显示当前目录中的所有文件

                                ls  Linux和macOS下显示当前目录中的所有文件

5、在终端运行python程序

        windows:先cd到该目录下,再dir确定这个文集夹中包含X.py文件 ,直接python X.py运行。

        linux:先cd到该目录下,再ls确定这个文集夹中包含X.py文件 ,直接python X.py运行。

第二章 变量和简单数据类型

1、运行hello_world.py 时发生的情况

print('Hello python word!')   

运行hello_world.py 时,.py可以指出这是一个python程序,因此编辑器将使用python解释器来云不行它。

注意使用的不是printf

2、变量

message ='Hello Python world!'
print(message)

输出:

Hello Python world!

其中message为变量,python始终记录变量的最新值

有关变量的规则:

①变量名只能包含字母、数字和下划线(不能用数字打头)

②变量名中不能含有空格,但能使用下划线来分隔其中的单词

③不要将python关键字和函数名用作变量名

④变量名应既简短又具有描述性

⑤慎用小写字母l和大写字母O

Track back:

指一条记录,在解释器中指出解释器尝试运行代码时,在哪陷入困境。

Trackback(most recent call last):
    File 'hello_world.py',line2,in<module>
        print(mesage)
    NameError:name 'mesage' is not defined

其中    File 'hello_world.py',line2,in<module>列出第二行有错误,

                print(mesage)为错误点

                NameError:name 'mesage' is not defined 为错误类型(此处为名称错误)

Name Error 一般有两种①变量赋值②输入变量名时拼写不正确

寻求帮助(Stack Overflow Redit):

            你想做什么?------>应尽可能具体

            你已尝试哪些方式?------>提供足够细节

            结果如何?------>知道准确的错误消息很有用

3、字符串

一系列字符,在python中用括号括起来的都是字符串,可以是单引号或者双引号。

使用方法修改字符串的大小写
name = 'ada lovelace'
print(name.title())

输出

Ada Lovelace

方法title()为对数据的操作,把首字母大写,并把非首字母大写的改为小写。

方法是python对数据执行的操作。()内为额外信息。

相似的有 name.upper()都大写

                name.lower()都小写     <-----可用于存储数据

在字符串中使用变量

          f"{}"称为f字符串

first_name = "ada"
last_name = "lovelace"
full_name = f"{first_name}{last_name}"
print(full_name)

        python通过把花括号内的变量替换为其值来设置字符串的格式。

使用指标符或换行符来添加空白

        制表符指相当于tab,首行缩进\t,换行符为\n

删除空白

        使字符串末尾没有空白:rstrip()

    last_name.rstrip()

    last_name = last_name.rstrip()

        剔除开头的空白lstrip(),同时剔除字符串两边的空白strip()

注意:单引号与撇号可能导致错误。请正确地使用单引号和双引号。

4、数

整数

        可用+  -  *  / 表示加减乘除, **表示平方,用()修改运算次序。

浮点数

        带小数点的数都可以称为浮点数。(小数点可出现在数的任意位置)

整数和浮点数

        在其他任何运算中,如果一个操作数是整数,另一个操作数是浮点数,结果也总是浮点数。(结果包含的小数位数可能是不确定的。)

数中的下划线

        书写很大的数的时候,可使用下划线将其中的数字分组,使其清晰易读。python不会打印其中的下划线。

universe_age = 14_000_000_000 
print(universe_age)

输出14000000000

同时给多个变量赋值
x,y,z = 0 ,0 ,0

用逗号分开

常量

全大写来表示某个变量为常量,其值始终不变。python没有内置的常量类型。

MAX_CONNECTIONS = 5000

5、注释

        用#标识,让代码对你和其他人来说更容易理解。

第三章 列表简介

1、列表是什么?

列表是由一系列按特定顺序排列的元素组成。

python中,用[ ]表示列表,并用 , 分隔其中的元素。

bicycles = ['trek', 'cannondale', 'redline', 'specialized']

print(bicycles)

输出:

['trek', 'cannondale', 'redline', 'specialized']
访问列表元素:

列表是有序的集合,可用元素位置(索引)告诉python。索引是从0开始。

bicycles = ['trek', 'cannondale', 'redline', 'specialized']

print(bicycles[0])

输出:

trek

如果:

bicycles = ['trek', 'cannondale', 'redline', 'specialized']

print(bicycles[0].title())

输出:

Trek

当索引指令为-1时,返回最后一个列表元素。同理-2为倒2,-3为倒3.

bicycles = ['trek', 'cannondale', 'redline', 'specialized']

print(bicycles[-1])

输出:

specialized

使用列表中的各个值:
message = f"My first bicucle was a {bicycals[0].title()}"
print(message)

输出:

My first bicycle was a Trek.

2、修改,添加和删除元素

修改元素

与访问很像,直接重新赋值覆盖。

motorcycles = ['honda', 'yamaha', 'suzuki'] 
motorcycles[0] = 'ducati'
print(motorcycles)

输出:

['ducati', 'yamaha', 'suzuki']
添加元素

①列表末尾添加元素 append()

motorcycles.append('ducati') 

还可以创建空的列表,再用append()来添加元素

motorcycles = [] 
motorcycles.append('honda') 
motorcycles.append('yamaha') 
print(motorcycles)

输出:

['honda', 'yamaha']

②在列表中插入元素 insert()

motorcycles = ['honda','yamaha','suzuki']
motorcycles.insert(0,'ducati')
print(motorcycles)

输出:

['ducati','honda','yamaha','suzuki']
删除元素

①使用 del 语句,知道要删除元素的位置,删除后再无法访问

del motorcycle[0]

②使用 pop() 删除列表末尾的元素并可以接着使用它,相当于弹出栈顶元素。

poped_motorcycle = motorcycls.pop()
print(motorcycls)
print(poped_motorcycle)

# motorcycls.pop()是处理后的
# poped_motorcycle 被poped

输出:

['honda','yamaha']
suzuki

③使用pop(*)来删除任意位置的元素,在圆括号中指定要删除的元素索引,可以接着使用

first_owned = motorcycles.pop(0)

④根据值删除元素remove() 得知道删除元素的值。也可以接着使用值。remove()只删除第一个指定的值,如果要删除的值可能在列表里出现多次,就需要使用循环来确保每个值都删除。

motorcycles.remove('ducati')

3、组织列表

修改是永久性的

使用方法sort()对列表永久排序

sort( ) 即按照字母顺序排序,也可以用于数组排序

cars = ['bmw', 'audi', 'toyota', 'subaru']
cars.sort()
print(cars)

输出:

['audi', 'bmw',  'subaru','toyota']

若要与字母方向相反,用sort(reverse = True)

cars.sort(reverse = True)
print(cars)

输出:

['toyota','subaru','bmw', 'audi']
使用函数sorted()对列表临时排序

        sorted( )能按特定顺序显示列表元素,同时不影响原始排序

print(sorted(cars))
print(cars)

输出:

['audi', 'bmw',  'subaru','toyota']
['bmw', 'audi', 'toyota', 'subaru']

与字母方向相反,用sorted(reverse = True)

倒着打印列表

          reverse( ) 

car.reverse()
确定列表的长度

        用len( )

len(cars)

第四章 操作列表

1、便利整个列表

用for 循环

每一个缩进的代码行都是循环的一部分,避免缩进错误,不要漏了冒号:

magicians = ['a','b','c']
for magician in magicians :   
    print(magician)           

输出:

a
b
c

其中magician为任意词。

2、创建数值列表

使用函数range()
for value in range(1,5):
    print(value)

输出:

1
2
3
4

range()让python从指定一个值开始数,并在到达指定的第二个值时停止,故不包含5.

range(6)返回0~5共六个值。

使用rang()创建数字列表

使用 list( )

number = list(range(1,6))
print(number)

输出:

[1,2,3,4,5]

用range()时还可以指定步长

even_number = list(range(2,11,2)
print(number)

输出:

[2,4,6,8,10]

使用range()几乎可ui创建任何需要的数据集

squares = []
for value in range(1,11):
    square = value**2
    squares.sppend(square)
print(squares)

输出:

[1,4,9,16,25,49,64,81,100]
找出数字列表的最大值、最小值和总和

max(),min(),sum()

列表解析
squares = [value**2 for value in range(1,11)]
print(aquares)

square         是列表名,

value**2        是用于生成要存储到列表中的值,

for value in range(1,11)         是用于给表达式提供值

3、使用列表的一部分

切片

列表中的部分元素

players = ['charles', 'martina', 'michael', 'florence', 'eli'] 
print(players[0:3])

输出:

['charles', 'martina', 'michael']

切片与range()一样都是到第2个索引之前的元素后停止

如果没有指定第一个索引,python将自动从列表开头开始:

players = ['charles', 'martina', 'michael', 'florence', 'eli'] 
print(players[:4])

输出:

['charles', 'martina', 'michael', 'florence']

要让切片终止于列表末尾:

players = ['charles', 'martina', 'michael', 'florence', 'eli'] 
print(players[2:])

输出:

 ['michael', 'florence', 'eli'] 

最后三个还可以携程:

players = ['charles', 'martina', 'michael', 'florence', 'eli'] 
print(players[-3:])

输出:

 ['michael', 'florence', 'eli'] 
遍历切片

for循环中使用切片

for player in players[:3]:
    print(player.title())

复制列表

[:]

print(players[:])
friend_foods = my_foods[:]

把my_foods的副本给friend_food

若为friend_foods = mu_foods则两个都指向my_foods这个列表

4、元组

python 将不能修改的值称为不可变的,而不可变的列表称为元组。

定义元组 

()

dimensions = (200,50)
print(dimensions[0])
print(dimensions[1])

输出:

200
50

注意:元组是由','标识的,()只是让元组看起来更整洁。

如果定义只包含一个元素的元组,必须再这个元素后面加上’,‘

my_t = (3,)

便利元组中的所有值

用for循环:

dimensions = (200,50)
for dimension in dimensions:
    print(dimentsion)

输出:

200
50

修改元组变量

元组的元素不能修改,但存储元组的变量可赋值

dimensions = (200,50)
print dimensions

输出:

200
50
dimensions = (400,100)
print dimensions

输出

400
100

第五章 if语句

1、示例

cars = ['audi', 'bmw', 'subaru', 'toyota']
for car in cars:
    if car == 'bmw':
        print(car.upper())
    else:
        print(car.title())

输出:

Audi
BMW
Subaru
Toyota

2、条件测试

 ==  检查是否相等,会区分大小写

!=  检查是否不相等

<               小于

<=                小于等于

>                大于

>=                大于等于

可用and/or 检查多个条件

在运算符的两边加一个空格,便于看代码

检查特定值是否包含在列表中

in not in 

available_toppings = ['mushrooms', 'olives', 'green peppers']
'mushrooms' in available_toppings

输出:

True
if user not on banned_users:
    print(..)

3、if 语句

简单的if语句
if conditional_test:
    do something

if-else语句

两种情况:

if age < 4:
    print()
else :
    print()

if-elif-else结构

超过两种情况

elif可以用多个elif,其中else可省略

if age < 4:
    print()
elif age < 18:
    print()
else :
    print()

使用if 语句处理列表

在运行for循环前确定列表是否为空很重要

if requesteds:

    for ...

requested_toppings = ['mushrooms', 'french fries', 'extra cheese']

for requested_topping in requested_toppings:
    if requested_topping = 'mushrooms':
        print("Adding " + requested_topping + ".")
    else:
        print("Sorry, we don't have " + requested_topping + ".")
        
print("\nFinished making your pizza!")
Adding mushrooms.
Sorry, we don't have french fries.
Adding extra cheese.

Finished making your pizza!

第六章 字典

1、一个简单的字典

alien_0 = {'color': 'green', 'points': 5}
print(alien_0['color'])
print(alien_0['points'])

输出:

green
5

字典aline_0存储了颜色和分数

2、使用字典

{}

里面放一系列键值对,中间用','分隔,键值对是两个相关联的值。

访问字典中的值

要获取与键值相关联的值,可依次指定字典名和放在[ ]内的键。

alien_0 = {'color': 'green'}
print(alien_0['color'])

输出:

green

添加键值对

可依次指定字典名,用[ ]括起键和相关联的值。

alien_0['x'] = 0
alien_0['y'] = 25
print(alien_0)
{'color': 'green', 'points': 5,'y':25,'x':0}

修改字典中的值

指定字典名,用[  ]阔起键,以及与该键相关联的新值。

alien_0['colcr'] = 'yellow'

删除键值对

del 永远消失

del alien_0['color']

由类似对象组成的字典

用多行来定义字典,在输入{}之后用回车并在下一行缩进四个空格,并在每一个键值对后面加逗号。

favorite_languages = {
    'jen': 'python',
    'sarah': 'c',
    'edward': 'ruby',
    'phil': 'python',
    }

用get()来访问值

指定键值可能不存在的情况

A = alien_0.get('points','Nopoint value')
print(point_value)

书上说如果没有points则会返回Nopoint value,若有points,则返回points,但我的代码运行不是这样

调用get()时,若没有指定第二个参数且指定键不存在

python将返回None

3、遍历字典

遍历所有键值对

for循环  items()

user_0 = {'username': 'efermi',
          'first': 'enrico',
          'last': 'fermi',
          }

for key, value in user_0.items():
    print(f"\nKey: {key}")
    print(f"Value: {value}")

输出:

Key: username
Value: efermi

Key: first
Value: enrico

Key: last
Value: fermi

items()返回一个键值对列表

把每一个键值对赋值给指定的变量

遍历字典中的所有键

不需要使用字典中的值时使用.keys()

for name in favorite_languages.keys():
   print(name.titles())

遍历字典时,会默认遍历所有的键,即keys()返回一个列表,其中包含字典中的所有键。

按特定顺序遍历字典中的所有键

sorted()临时排序,不影响原始排序。

for name in sorted(favorite_languages.keys()):
   print(name.titles())

遍历字典中的所有值

values()来返回一个值列表,不包含任何值

for language in favorite_languages.values():
   print(language.titles())

这种做法提取字典中所有的值,而没有考虑是否重复

若有重复项,

①可使用集合set(),通过对包含重复元素的列表调用set().

for language in set(favorite_languages.values()):
   print(language.titles())

②可使用一对{}直接创建集合,并在其中用‘,’分隔元素。

  集合不能包含重复的元素

languages = {'python','ruby','python','c'}

集合和字典很容易混淆,都由{}定义。当{}内没有键值对时,定义的很有可能时集合,不同于列表和字典,集合不会以特定的顺序存储元素。

4、嵌套

将一系列字典存储在列表中,或将列表作为值存储在字典中,此为嵌套。

字典列表

首先创建n个字典,然后将这些字典都存储到一个列表中。

先创建一个空列表,再用range()生成字典,将字典放进列表。

alien_0 = {'color': 'green', 'points': 5}
alien_1 = {'color': 'yellow', 'points': 10}
alien_2 = {'color': 'red', 'points': 15}
aliens = [alien_0, alien_1, alien_2]

在字典中存储列表

首先创建一个字典,每当需要在字典中将一个键关联到多个值时,都可以在字典中嵌套一个列表。

pizza = {
    'crust': 'thick',
    'toppings': ['mushrooms', 'extra cheese'],
    }

在字典中存储字典
users = {'aeinstein': {'first': 'albert',
                       'last': 'einstein',
                       'location': 'princeton'},
         'mcurie': {'first': 'marie',
                    'last': 'curie',
                    'location': 'paris'},
         }

第七章 用户输入和while循环

1、函数input()的工作原理

        函数input()让程序暂停运行,等待用户输入一些文本。获取用户输入后,python将其赋给一个变量,以便使用。

prompt = "\nTell me something, and I will repeat it back to you:"
message = input(prompt)
print(message)

使用int()来获取数值的输入

函数input()时,python将用户输入解读为字符串。

函数int()时,让python输入视为数值。

height = input("How tall are you, in inches? ")
height = int(height)

if height >= 36:
    print("\nYou're tall enough to ride!")
else:
    print("\nYou'll be able to ride when you're a little older.")

求模运算符

% 将两个数相除并返回余数

4%3   
6%3

输出

1
0

2、while 循环简介

while循环不断运行,直到指定的条件不满足为止。

使用while循环
current_number = 1
while current_number <= 5:
    print(current_number)
    current_number += 1

输出:

1
2
3
4
5

让用户选择如何退出

定义了一个退出值,只要用户输入的不是这个值,程序就将接着运行。

prompt = "\nPlease tell me a city you have visited:"
prompt += "\n(Enter 'quit' when you are finished.) "

message = ' '
while message != 'quit':
    message = input(prompt)
    print(message)

以上不足之处是quit也被打印出来了,可改为:

prompt = "\nPlease tell me a city you have visited:"
prompt += "\n(Enter 'quit' when you are finished.) "

message = ' '
while message != 'quit':
    message = input(prompt)
    if message != 'quit':
        print(message)

使用标志

flag(标志)简化了while语句

prompt = "\nTell me something, and I will repeat it back to you:"
prompt += "\nEnter 'quit' to end the program. "
  
active = True
while active:
    message = input(prompt)
    
    if message == 'quit':
        active = False
    else:
        print(message)

使用break退出循环

立即退出while循环,不再运行循环内的余下代码。 退出所有循环。

while True:
    city = input(prompt)
    if city == 'quit':
        break
    else:
        print()

在循环中使用continue

执行continue语句,让python忽略余下的代码,并返回循环的开头。退出本次循环,进入下一循环。

Ctrl +C  退出无限循环

3、使用while 循环处理列表和字典

不应在for循环中修改列表,否则将导致python难以跟踪其中的元素。

可以用while 循环。

在列表之间移动元素
unconfirmed_users = ['alice', 'brian', 'candace']
confirmed_users = []

# Verify each user, until there are no more unconfirmed users.
#  Move each verified user into the list of confirmed users.
while unconfirmed_users:
    current_user = unconfirmed_users.pop()
    
    print("Verifying user: " + current_user.title())
    confirmed_users.append(current_user)
    
# Display all confirmed users.
print("\nThe following users have been confirmed:")
for confirmed_user in confirmed_users:
    print(confirmed_user.title())

输出:

Verifying user: Candace
Verifying user: Brian
Verifying user: Alice

The following users have been confirmed:
Candace
Brian
Alice
删除为特定值的所有列表元素

remove() 与while一起用

删除列表中所有为特定值的元素

pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
print(pets)

while 'cat' in pets:
    pets.remove('cat')
    
print(pets)

输出:

['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
['dog', 'dog', 'goldfish', 'rabbit']

使用用户输入来填充字典
responses = {}

# Set a flag to indicate that polling is active.
polling_active = True

while polling_active:
    # Prompt for the person's name and response.
    name = input("\nWhat is your name? ")
    response = input("Which mountain would you like to climb someday? ")
    
    # Store the response in the dictionary:
    responses[name] = response
    
    # Find out if anyone else is going to take the poll.
    repeat = input("Would you like to let another person respond? (yes/ no) ")
    if repeat == 'no':
        polling_active = False
        
# Polling is complete. Show the results.
print("\n--- Poll Results ---")
for name, response in responses.items():
    print(name + " would like to climb " + response + ".")

第八章 函数

1、定义函数

def函数定义

greet_user()为函数,调用它时只需要输入greet_user()即可。

def greet_user(username):
    """Display a simple greeting."""
    print("Hello, " + username.title() + "!")
    
greet_user('jesse')

输出:

Hello, Jesse!

文档字符串(docstring),用三个引号括起来,描述了函数是做什么的。

向函数传递信息

在()中添加一个变量,可让函数接受你给该变量指定的值。

def greet_users(names):
    """Print a simple greeting to each user in the list."""
    for name in names:
        msg = "Hello, " + name.title() + "!"
        print(msg)

usernames = ['hannah', 'ty', 'margot']
greet_users(usernames)

输出

Hello, Hannah!
Hello, Ty!
Hello, Margot!

实参和形参

username 为形参  jesse 为实参

2、传递参数

即存在多个实参的情况

位置实参:实参的顺序与形参的顺序相同

关键字实参:每个实参都由变量名和值组成;还可使用列表和字典。

位置参数

顺序相同

def describe_pet(pet_name, animal_type='dog'):
    """Display information about a pet."""
    print("\nI have a " + animal_type + ".")
    print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet('harry', 'hamster')

输出:

I have a hamster.
My hamster's name is Harry.

①多次调用函数

②位置参数的序列很重要

关键字实参

传递给函数名称值对,直接在实参中将名称和值关联起来。

def describe_pet(pet_name, animal_type='dog'):
    """Display information about a pet."""
    print("\nI have a " + animal_type + ".")
    print("My " + animal_type + "'s name is " + pet_name.title() + ".")
    
# A dog named Willie.
describe_pet(pet_name='harry', animal_type='hamster')

输出:

I have a hamster.
My hamster's name is Harry.

默认值

def describe_pet(pet_name, animal_type='dog'):
    """Display information about a pet."""
    print("\nI have a " + animal_type + ".")
    print("My " + animal_type + "'s name is " + pet_name.title() + ".")
    
# A dog named Willie.
describe_pet(pet_name = 'willie') 
#或者  describe_pet('willie') 

是指给形参默认值    animal_type='dog'

注意:必须先在形参列表中列出没有默认值的形参,再列出有默认值的实参。

          让python依然能够正确地解读位置实参。

等效的函数调用
def describe_pet(pet_name, animal_type='dog'):
    """Display information about a pet."""
    print("\nI have a " + animal_type + ".")
    print("My " + animal_type + "'s name is " + pet_name.title() + ".")   
describe_pet('willie')
describe_pet(pet_name='willie')

describe_pet('harry', 'hamster')
describe_pet(pet_name='harry', animal_type='hamster')
describe_pet(animal_type='hamster', pet_name='harry')

注意:任何情况下都必须给pet_name提供实参。

        指定实参时可采用位置方式,也可采用关键字方式。

3、返回值

函数可以处理一些数据,并返回一个或一组值,称为返回值。

可以用return语句将值返回到调用函数的代码行。

返回简单值

return

​def get_formatted_name(first_name, last_name):
 
    full_name = first_name +  ' ' + last_name
    return full_name.title()
    
musician = get_formatted_name('jimi', 'hendrix')
print(musician)

输出

Jimi Hendrix
让参数变成可选的

将该可能有或可能无的形参的默认值设为空字符串,并将其转移到形参列表的末尾。

def get_formatted_name(first_name, last_name, middle_name=''):
    """Return a full name, neatly formatted."""
    if middle_name:
        full_name = first_name + ' ' +  middle_name + ' ' + last_name
    else:
        full_name = first_name + ' ' + last_name
    return full_name.title()
    
musician = get_formatted_name('jimi', 'hendrix')
print(musician)

musician = get_formatted_name('john', 'hooker', 'lee')
print(musician)

输出:

Jimi Hendrix
John Lee Hooker

返回字典
def build_person(first_name, last_name):
    """Return a dictionary of information about a person."""
    person = {'first': first_name, 'last': last_name}
    return person

musician = build_person('jimi', 'hendrix')
print(musician)
def build_person(first_name, last_name, age=None):
    """Return a dictionary of information about a person."""
    person = {'first': first_name, 'last': last_name}
    if age:
        person['age'] = age
    return person

musician = build_person('jimi', 'hendrix', age=27)
print(musician)

age是形参,None是特殊值,表示变量没有值,可视为占位,相当于False。如果函数调用中包含形参age的值,这个值将被存储到字典中。

4、传递列表

将包含名字的列表传递给一个名为greet_users()的函数。

def greet_users(names):
    """Print a simple greeting to each user in the list."""
    for name in names:
        msg = "Hello, " + name.title() + "!"
        print(msg)

usernames = ['hannah', 'ty', 'margot']
greet_users(usernames)

输出:

Hello, Hannah!
Hello, Ty!
Hello, Margot!
禁止函数修改列表

可以将列表副本传递给函数

fuction_name(list_name[:])

5、传递任意数量的实参

预先不知道函数需要接受多少个实参,用* 创造这个形参

例如:*toppings,不管调用语句提供了多少实参都可以。

        *让python创造一个名为toppings的空元组,并将所有值都封装到元组中

def make_pizza( *toppings):
  
        print( toppings)
        
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')

输出:

('pepperoni',)
('mushrooms', 'green peppers', 'extra cheese')

结合使用位置实参和任意数量实参

        若要接受不同类型的实参,必须将接纳任意数量实参的形参放最后,python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。

def make_pizza(size, *toppings):
    """Summarize the pizza we are about to make."""
    print("\nMaking a " + str(size) +
          "-inch pizza with the following toppings:")
    for topping in toppings:
        print("- " + topping)
        
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

输出:

Making a 16-inch pizza with the following toppings:
- pepperoni

Making a 12-inch pizza with the following toppings:
- mushrooms
- green peppers
- extra cheese

使用任意数量的关键字实参

可将函数编写能接受任意数量的键值对

def build_profile(first, last, **user_info):
    """Build a dictionary containing everything we know about a user."""
    profile = {}
    profile['first_name'] = first
    profile['last_name'] = last
    for key, value in user_info.items():
        profile[key] = value
    return profile

user_profile = build_profile('albert', 'einstein',
                             location='princeton',
                             field='physics')
print(user_profile)

输出:

{'first_name': 'albert', 'last_name': 'einstein', 'location': 'princeton', 'field': 'physics'}

**user_info:让python创建一个名为user_info的空字典。并将收到的所有名称值都放到这个字典中。

6、将函数存储在模块中

再将模块导入到主程序中,import语句允许在当前运行的程序文件中使用模块中代码。

导入整个模块

先创建模块(扩展名为.py的文件)pizza.py

def make_pizza(size, *toppings):
    """Summarize the pizza we are about to make."""
    print("\nMaking a " + str(size) +
          "-inch pizza with the following toppings:")
    for topping in toppings:
        print("- " + topping)
        

另一个py文件:

import  pizza

make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
导入函数中的所有函数

使用*      无需使用句点表示法

from pizza import *

使用as给函数指定别名

别名:函数的另一个名称

from pizza import make_pizza as mp
导入特定的函数
from module_name import function_name

就可以不用pizza.make这样的格式

还可以通过逗号分隔函数名,导入任意数的函数

7、函数编写指南

只在其中使用小写字母和下划线。

第九章 类

1、创建和使用类

class Dog():
    """A simple attempt to model a dog."""
    
    def __init__(self, name, age):
        """Initialize name and age attributes."""
        self.name = name
        self.age = age
        
    def sit(self):
        """Simulate a dog sitting in response to a command."""
        print(self.name.title() + " is now sitting.")

    def roll_over(self):
        """Simulate rolling over in response to a command."""
        print(self.name.title() + " rolled over!")

首字母大写为类,此处定义了一个名为Dog的类

__init__()称为方法

self, name, age 为三个形参,python自动传入实参self,每个与实例相关联的方法调用都自动传递实参self,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。

self会自动传递,因此不需要传递它。

根据类创建实例
my_dog = Dog('Willie', 6)

print(f"My dog's name is {my_dog.name}.")
print(f"My dog is {my_dog.age} years old.")

my_dog为小写的名称,指根据类创建的实例

my_dog.name  指的是访问属性

Dog类引用这个属性时,使用的是self.name

调用方法:

可指定实例的名称,和要调用的方法并用句点分割。

my_dog = Dog('Willie', 6)
my_dog.sit()
my_dog.roll_over()

2、使用类和实例

给属性指定默认值
class Car:
    """A simple attempt to represent a car."""

    def __init__(self, make, model, year):
        """Initialize attributes to describe a car."""
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0
        

修改属性的值

有三种方式

①直接通过实例进行修改

my_dog.age = 23

②通过方法修改属性的值

def update_odometer(self.mileage):
    self.odometer_reading = mileage
my_new_car.update_odometer(23)

③通过方法对属性的值进行递增

def increment_odometer(self,miles):
    self.odometer_reading += miles

3、继承

类并非总要从0开始写,可以继承另一个类,自动获得另一个类的所有属性和方法。

原有的类称为父类,而新的类称为子类。

子类继承了父类的所有属性和方法,同时还可以定义自己的属性和方法。

子类的方法__init__( )
class ElectricCar(Car):
    """Represent aspects of a car, specific to electric vehicles."""
    
    def __init__(self, make, model, year):
        """
        Initialize attributes of the parent class.
        Then initialize attributes specific to an electric car.
        """
        super().__init__(make, model, year)

my_tesla = ElectricCar('tesla', 'model s', 2019)
print(my_tesla.get_descriptive_name())

supper( )

super()是一个特殊函数,让你能够调用父类(car)的方法。

此行让python调用Car类的方法__init__() , 让ElectricCar 实例包含这个方法中定义的所有属性,父性也称超类,super从此而来。

给子类定义属性和方法
class ElectricCar(Car):
    """Represent aspects of a car, specific to electric vehicles."""

    def __init__(self, make, model, year):
        """
        Initialize attributes of the parent class.
        Then initialize attributes specific to an electric car.
        """
        super().__init__(make, model, year)
        self.battery_size = 75

    def describe_battery(self):
        """Print a statement describing the battery size."""
        print(f"This car has a {self.battery_size}-kWh battery.")

my_tesla.describe_battery()

重写父类的方法

可在子类中定义一个与要重写的父类方法同名的方法

class ElectricCar(Car):
 #--ship--
    def fill_gas_tank(self):
        print('')

调用方法fill_gas_tank(),python忽略car类的方法

将实例用作属性

将类的一部分提取出来,作为一个独立的类。

可以将大型类拆分成多个协同工作的小类。

class Battery:
    """A simple attempt to model a battery for an electric car."""
    
    def __init__(self, battery_size=75):
        """Initialize the battery's attributes."""
        self.battery_size = battery_size

    def describe_battery(self):
        """Print a statement describing the battery size."""
        print(f"This car has a {self.battery_size}-kWh battery.")

    def get_range(self):
        """Print a statement about the range this battery provides."""
        if self.battery_size == 75:
            range = 260
        elif self.battery_size == 100:
            range = 315
            
        print(f"This car can go about {range} miles on a full charge.")


class ElectricCar(Car):
    """Represent aspects of a car, specific to electric vehicles."""
    
    def __init__(self, make, model, year):
        """
        Initialize attributes of the parent class.
        Then initialize attributes specific to an electric car.
        """
        super().__init__(make, model, year)
        self.battery = Battery()

my_tesla = ElectricCar('tesla', 'model s', 2019)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()

Battery没有继承任何类,ElectricCar类中添加了一个名为self.battery的属性。这行代码让python常见一个新的battery实例。

4、导入类

将类存储在模块中,然后在主程序中导入所需的模块

导入单个类
from car import Car
在一个模块中导入多个类
from car import Car , ElectricCar

导入整个模块
import car
导入模块中导入另一个模块
from module_name import *
使用别名
from electric_car import ElectricCar as Ec
python标准库

模块random中的randint()将两个整数作为参数,并随机返回一份位于两整数之间的整数。

choice()将一个列表或元组作为参数,并随机返回其中的一个元素。

第十章 文件和异常

1、从文件中读取数据

读取整个文件

先要打开文件open()只能接受一个参数,要打开文件的名称。

with open('pi_digits.txt') as  file_object:
    contents = file_object.read()
print(contents)

with在不需要访问文件后将其关闭。(由python确定关掉时间)

也可以调用open()close()来打开和关闭文件,但是如果程序存在bug导致方法close()未执行,文件将不会关闭。

read()读取这个文件的全部内容,并将其作为一个长长的字符串赋给变量contents.

但是read()返回会多一个空字符串,即输出末尾多一个空行。

要删掉空行,可在函数调用中print()中使用rstrip()

print(contents.rstrip())

文件路径

在打开不在程序文件所属目录中的文件。

with open('test_files/filename.txt') as file_object:

注意:显示文件路径时,windows用反斜杠(\)而不是斜杠(/),但是代码中仍可以使用斜杠(/)

file_path = '/home/ehmatthes/other_files/test_files/filename.txt'
    with open(file_path) as file_object:

逐行读取

对文本对象使用for循环

filename = 'pi_digits.txt'

with open(filename) as file_object:
    for line in file_object:
        print(line)
   

若不要空格则:

 print(line.rstrip())

去掉了右边的空格,两边则用strip()

创建一个包含文件各行内容的列表

即在with代码块外访问文件的内容

filename = 'pi_digits.txt'

with open(filename) as file_object:
    lines = file_object.readlines()

for line in lines:
    print(line.rstrip())

readlines()从文件中读取每一行,并将其存储在一个列表中。

使用文件的内容
filename = 'pi_million_digits.txt'

with open(filename) as file_object:
    lines = file_object.readlines()

pi_string = ''
for line in lines:
    pi_string += line.strip()

print(pi_string)
print(len(pi_string))

注意:从文本中读取时,所有文本读为字符串,若读取的是数,并要用作数值,则必须用函数int(),或float()将其转换为浮点数。

检查字符串是否包括
for line in lines:
    pi_string += line.strip()
    
birthday = input("Enter your birthday, in the form mmddyy: ")
if birthday in pi_string:
    print("Your birthday appears in the first million digits of pi!")
else:
    print("Your birthday does not appear in the first million digits of pi.")

2、写入文件

写入空文件
filename = 'programming.txt'

with open(filename, 'w') as file_object:
    file_object.write("I also love finding meaning in large datasets.\n")
    file_object.write("I love creating apps that can run in a browser.\n")

'w'表示写入模式

'a'表示附加模式

'r+'表示读写模式

'r'读取模式

若写入的文件不存在,函数open()将自动创建它

若用'w'打开文件时,该文件已存在,python将在返回文件对象前清空改文件的内容。(把原来写的东西清空)

注意:python只能将字符串写入文本文件

写入多行

write()不会在写入的文本末尾添加换行符,需要write()中包含换行符。

添加到文件

'a'模式将内容附加到文件末尾,而不是覆盖文件原来的内容。

3、异常

处理ZeroDivisionError异常

像使用5/0,就会报错。

使用try-except代码块
try:
    print(5/0)
except ZeroDivisionError:
    print("you can't divide by zero")

使用异常避免崩溃

提示用户提供有效输入,而不至于崩溃。

else代码块

try-except-else代码块

try:
    answer = int(first_number)/int(second_number)
except ZeroDivisionError:
    print("you can't  ...zero")
else:
    print(answer)
分析文本

split()可根据一个字符串创造一个单词列表。

以空格为分隔符将字符串分拆成多个部分,并将这些部分都存储到一个列表中。

filename = 'alice.txt'

try:
    with open(filename, encoding='utf-8') as f:
        contents = f.read()
except FileNotFoundError:
    print(f"Sorry, the file {filename} does not exist.")
else:
    # Count the approximate number of words in the file.
    words = contents.split()
    num_words = len(words)
    print(f"The file {filename} has about {num_words} words.")
使用多个文件

定义函数用来分析文件

可用循环从文件名称列表中进行依次调用

静默失败

在except代码块中明确告诉python什么都不要做

使用pass 语句

    try:
        with open(filename, encoding='utf-8') as f:
            contents = f.read()
    except FileNotFoundError:
        pass

4、存储数据

使用模块json来存储数据

模块json可以让你把简单的python数据结构转储到文件中,并在程序再次运行时加载该文件中的数据。还可用于python间的分享数据。

使用json.dump()和json.load()

函数json.dump()接受两个实参:要存储的数据,文件对象。

import json

numbers = [2, 3, 5, 7, 11, 13]

filename = 'numbers.json'
with open(filename, 'w') as f:
    json.dump(numbers, f)

将数字列表存到numbers.json中了

若使用json.load()则:

import json

filename = 'username.json'

with open(filename) as f:
    username = json.load(f)
    print(f"Welcome back, {username}!")

 username = json.load(f)

将存储在numbers.json中的信息赋给变量username

保存和读取用户生成的数据

使用json.dump()和json.load()与try_except_else结合

import json

filename = 'username.json'

try:
    with open(filename) as f:
        username = json.load(f)
except FileNotFoundError:
    username = input('What id your name?')
    with open(filename,'w') as f:
        json.dump(username,f)
        print(f"we'll remenber you...{username}!")
else:    
    print(f'wlcome back,{username}!')

重构

将大部分逻辑放到一个或多个函数中

例如将上面改为

import json

def greet_user():

    filename = 'username.json'

    try:
        with open(filename) as f:
            username = json.load(f)
    except FileNotFoundError:
        username = input('What id your name?')
        with open(filename,'w') as f:
            json.dump(username,f)
            print(f"we'll remenber you...{username}!")
    else:    
        print(f'wlcome back,{username}!')
greet_user()

或者写成两个函数,然后一个内部调用另一个

第十一章 测试代码

1、测试函数

学习如何测试函数和类,并将知道改为项目编写多少个测试。(自动测试)

单元测试和测试用例

模块unittest提供了代码测试工具

①测试单元:用于核实函数的某个方面没有问题

②测试用例:是一组单元测试,它们一道核实函数在各种情性下的行为都符合要求。

③可以全覆盖的测试,但对大型项目,通常,最初只要针对代码的重要行为编写测试即可。

可通过的测试

要为函数编写测试用例,可先导入模块unittest和要测试的函数,再创造一个继承unittest.TestCase的类,并编写一系列方法对函数行为的不同方面进行测试。

import unittest #导入模块unittest

from name_function import get_formatted_name #要测试的函数

class NamesTestCase(unittest.TestCase): #创建一个继承unittest.TestCase的类
    """Tests for 'name_function.py'."""
    
    def test_first_last_name(self):  #以test开头
        """Do names like 'Janis Joplin' work?"""
        formatted_name = get_formatted_name('janis', 'joplin') #两个实参
        self.assertEqual(formatted_name, 'Janis Joplin')
         
if __name__ == '__main__':
    unittest.main()

assertEqual 为断言:核实得到的结果是否与期望的结果一致。

将formatted_name的值与后面字符串比较

运行后会显示有几个测试通过,用了多久和ok。

Ran 1 tests in 0.008s

OK

未通过的测试

会显示ERROR

添加新测试

在Class Names TestCase (unittest.TestCase)下加入def

方法名必须以test_打头。

2、测试类

各种断言方法

unittest.TwatCase类中提供了很多断言方法

①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()只需要创建这些对象一次,就能在每个测试方法中使用。

若:TestCase类中包含了方法setup(),python将先运行它,再运行各个以test_打头的方法。

Class TestAnonymous Survey (unittest.TestCase):

        def setup(self):

        question = ..

        self.my_survey = ...

        self.responses = ...

        def test_store_single_response(self)        

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值