python的基本使用方法

Python

python函数
print("hello")
hello
name = "hello world"
print(name.title)
<built-in method title of str object at 0x10dbda6b0>

字符串改为大写

print(name.upper())
HELLO WORLD

字符串改为小写

str1 = "HELLO WORLD"
print(str1.lower())
hello world

使用“+”拼接字符串

print(name + " and "+str1)
hello world and HELLO WORLD

strip() / rstrip() / lstrip()

要确保字符串开头、末尾没有空白,可使用方法strip()

str1 = "   hello  python3     "
str2 = "hello python "
print("--"+ str1.strip() + "--")
--hello  python3--

要确保字符串末尾没有空白,可使用方法rstrip()

print(str2.rstrip())  ## 临时的
hello python
print("' "+ str2 + "' ")
' hello python       ' 

要确保字符串开头没有空白,可使用方法lstrip()

print("-"+str2.lstrip())
-hello python       

次方运算

print(3 ** 2)
9
print(3 ** 3)
27

避免类型错误 str()

age = 23
message = "Happy " + age + "rd Birthday"
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-21-5bbdce04c224> in <module>
      1 age = 23
----> 2 message = "Happy " + age + "rd Birthday"


TypeError: must be str, not int
message = "Happy " + str(age) + "rd Birthday"
print(message)
Happy 23rd Birthday
import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

列表

列表 由一系列按特定顺序排列的元素组成。你可以创建包含字母表中所有字母、数字0~9或所有家庭成员姓名的列表;也可以将任何东西加入列表中,其中的元素之间可以没有 任何关系。鉴于列表通常包含多个元素,给列表指定一个表示复数的名称(如letters 、digits 或names )是个不错的主意。

bicycles = ['trek', 'cannondale', 'redline', 'specialized'] 
print(bicycles)
['trek', 'cannondale', 'redline', 'specialized']
print(bicycles[0])
trek
print(bicycles[0].title()) #这个示例的输出与前一个示例相同,只是首字母T是大写的
Trek
print(bicycles[-1])
specialized

这些代码返回’specialized’ 。这种语法很有用,因为你经常需要在不知道列表长度的情况下访问最后的元素。这种约定也适用于其他负数索引,例如,索引-2 返回倒数第二个列表元素,索引-3返回倒数第三个列表元素,以此类推。

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

你创建的大多数列表都将是动态的,这意味着列表创建后,将随着程序的运行增删元素。例如,你创建一个游戏,要求玩家射杀从天而降的外星人;为此,可在开始时将一些外 星人存储在列表中,然后每当有外星人被射杀时,都将其从列表中删除,而每次有新的外星人出现在屏幕上时,都将其添加到列表中。在整个游戏运行期间,外星人列表的长度 将不断变化。

修改

print(bicycles)
bicycles[0] = 'sifei'
print(bicycles)
['expecially', 'cannondale', 'redline', 'specialized']
['sifei', 'cannondale', 'redline', 'specialized']

添加 append()

bicycles.append('huofei')
print(bicycles)
['sifei', 'cannondale', 'redline', 'specialized', 'huofei']

插入 insert()

bicycles.insert(1,'mountain bike')
print(bicycles)
['sifei', 'mountain bike', 'cannondale', 'redline', 'specialized', 'huofei']

删除 del()

你经常需要从列表中删除一个或多个元素。例如,玩家将空中的一个外星人射杀后,你很可能要将其从存活的外星人列表中删除;当用户在你创建的Web应用中注销其账户时, 你需要将该用户从活跃用户列表中删除。你可以根据位置或值来删除列表中的元素

del bicycles[3]
print(bicycles)
['sifei', 'mountain bike', 'cannondale', 'specialized', 'huofei']

删除 pop()

有时候,你要将元素从列表中删除,并接着使用它的值。例如,你可能需要获取刚被射杀的外星人的 x 和 y 坐标,以便在相应的位置显示爆炸效果;在Web应用程序中,你可能 要将用户从活跃成员列表中删除,并将其加入到非活跃成员列表中。 方法pop() 可删除列表末尾的元素,并让你能够接着使用它。术语弹出 (pop)源自这样的类比:列表就像一个栈,而删除列表末尾的元素相当于弹出栈顶元素

ans = bicycles.pop()
print(ans)
huofei
print(bicycles)
['sifei', 'mountain bike', 'cannondale', 'specialized']

假设列表中的自行车车是按购买时间存储的,就可使用方法pop() 打印一条消息,指出最后购买的是哪款自行车:

last_owned = bicycles.pop() 
print("The last bicycle I owned was a " + last_owned.title() + ".")
The last bicycle I owned was a Specialized.

弹出列表中任意位置的元素

实际上,你可以使用pop() 来删除列表中任何位置的元素,只需在括号中指定要删除的元素的索引即可。

once_owned = bicycles.pop(2)
print(once_owned)
cannondale

根据值删除元素 remove()

print(bicycles) # 有重复的sifei也没关系,因为列表元素之间没有关系
# ['sifei', 'mountain bike', 'Specialized', 'cannondale', 'sifei', 'huofei']
['sifei', 'mountain bike', 'Specialized', 'cannondale', 'sifei', 'huofei']

[‘sifei’, ‘mountain bike’, ‘Specialized’, ‘cannondale’, ‘sifei’, ‘huofei’]

bicycles.remove('sifei')
print(bicycles) # 删除了第一个sifei
# ['mountain bike', 'Specialized', 'cannondale', 'sifei', 'huofei']
['mountain bike', 'Specialized', 'cannondale', 'sifei', 'huofei']

组织列表

cars = ['audi','bmw','benci','toyota','honda']

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

cars.sort() # 按字母顺序,都是小写
print(cars)
['audi', 'benci', 'bmw', 'honda', 'toyota']

使用sorted()对列表进行临时排序

cars = ['audi','bmw','benci','toyota','honda']
sorted(cars)
print(cars)
['audi', 'bmw', 'benci', 'toyota', 'honda']

倒叙打印列表

cars.reverse()
print(cars)
['honda', 'toyota', 'benci', 'bmw', 'audi']

确定列表长度

print(len(cars))
5

在你需要完成如下任务时,len() 很有用:确定还有多少个外星人未被射杀,需要管理多少项可视化数据,网站有多少注册用户等。

操作列表

遍历列表

你经常需要遍历列表的所有元素,对每个元素执行相同的操作。例如,在游戏中,可能需要将每个界面元素平移相同的距离;对于包含数字的列表,可能需要对每个元素执行相 同的统计运算;在网站中,可能需要显示文章列表中的每个标题。需要对列表中的每个元素都执行相同的操作时,可使用Python中的for 循环。 假设我们有一个魔术师名单,需要将其中每个魔术师的名字都打印出来。为此,我们可以分别获取名单中的每个名字,但这种做法会导致多个问题。例如,如果名单很长,将包 含大量重复的代码。另外,每当名单的长度发生变化时,都必须修改代码。通过使用for 循环,可让Python去处理

print(bicycles)
['mountain bike', 'Specialized', 'cannondale', 'sifei', 'huofei']
for by in bicycles:
print(by)
mountain bike
Specialized
cannondale
sifei
huofei

创建数值列表

函数range()

for i in range(5):
print(i)
0
1
2
3
4

使用range()创建列表

numbers = list(range(1,6))
print(numbers) # 6之前的都打印了
[1, 2, 3, 4, 5]
numbers2 = list(range(1,10,2))
print(numbers2) # 指定步长
[1, 3, 5, 7, 9]

统计计算

max、min、sum

列表解析

前面介绍的生成列表的方式包含三四行代码,而列表解析让你只需编写一行代码就能生成这样的列表。列表解析将for循环和创建新元素的代码合并成一行,并自动附加新元素。

squares = [value**2 for value in range(1,11)]
print(squares)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

使用部分列表

切片

要创建切片,可指定要使用的第一个元素和最后一个元素的索引。与函数range() 一样,Python在到达你指定的第二个索引前面的元素后停止。要输出列表中的前三个元素,需要指定索引0~3,这将输出分别为0 、1 和2 的元素。

players = ['Curry','Lerbon','Harden','Durant','Davis']
print(players[0:3]) #[头:尾] 可以缺一
['Curry', 'Lerbon', 'Harden']
print(players[1:])
['Lerbon', 'Harden', 'Durant', 'Davis']
print(players[:4])
['Curry', 'Lerbon', 'Harden', 'Durant']

无论列表多长,这种语法都能够让你输出从特定位置到列表末尾的所有元素。本书前面说过,负数索引返回离列表末尾相应距离的元素,因此你可以输出列表末尾的任何切片。 例如,如果你要输出名单上的最后三名队员,可使用切片players[-3:]

print(players[-3:])
['Harden', 'Durant', 'Davis']

遍历切片

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

在很多情况下,切片都很有用。例如,编写游戏时,你可以在玩家退出游戏时将其最终得分加入到一个列表中。然后,为获取该玩家的三个最高得分,你可以将该列表按降序排列,再创建一个只包含前三个得分的切片。处理数据时,可使用切片来进行批量处理;编写Web应用程序时,可使用切片来分页显示信息,并在每页显示数量合适的信息。

复制列表

stars = players[:]
cp = players
print(stars)
print(cp)
['Curry', 'Lerbon', 'Harden', 'Durant', 'Davis', 'Kyrie']
['Curry', 'Lerbon', 'Harden', 'Durant', 'Davis', 'Kyrie']
players.append('Kyrie')
print(stars)
print(cp)
['Curry', 'Lerbon', 'Harden', 'Durant', 'Davis', 'Kyrie']
['Curry', 'Lerbon', 'Harden', 'Durant', 'Davis', 'Kyrie', 'Kyrie']

元组

列表非常适合用于存储在程序运行期间可能变化的数据集。列表是可以修改的,这对处理网站的用户列表或游戏中的角色列表至关重要。然而,有时候你需要创建一系列不可修改的元素,元组可以满足这种需求。Python将不能修改的值称为不可变值,而不可变的列表被称为元组。

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

TypeError                                 Traceback (most recent call last)

<ipython-input-97-ec422ee820dc> in <module>
----> 1 dimensions[0] = 210


TypeError: 'tuple' object does not support item assignment

修改元组变量

虽然不能修改元组的元素,但可以给存储元组的变量赋值。因此,如果要修改前述矩形的尺寸,可重新定义整个元组:

dimensions = (400, 100) 
for dimension in dimensions:
print(dimension)
400
100

if语句

检查条件

使用and检查多个条件

要检查是否两个条件都为True可使用关键字and将两个条件测试合而为一;如果每个测试都通过了,整个表达式就为True;如果至少有一个测试没有通过,整个表达式就为False

a = 10
b = 20
a > 8 and b < 22
True

使用or检查条件

关键字or也能够让你检查多个条件,但只要至少有一个条件满足,就能通过整个测试。仅当两个测试都没有通过时,使用or的表达式才为False。下面再次检查两个人的年龄,但检查的条件是至少有一个人的年龄不小于21岁:

a < 8 or b < 22
True

检查特定值是否在列表中

要判断特定的值是否已包含在列表中,可使用关键字in

'sifei' in bicycles
True
'huofei' not in bicycles
False
  • if-else
  • if-elif-else

字典

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

删除键值对

del alien_0['color']
print(alien_0)
{'points': 5}

遍历字典 items()

user_0 = { 'username': 'efermi', 'first': 'enrico', 'last': 'fermi', }
for key, value in user_0.items():  
print("\nKey: " + key)
print("Value: " + value)
Key: username
Value: efermi

Key: first
Value: enrico

Key: last
Value: fermi

顺序遍历所有键

字典总是明确地记录键和值之间的关联关系,但获取字典的元素时,获取顺序是不可预测的。这不是问题,因为通常你想要的只是获取与键相关联的正确的值。 要以特定的顺序返回元素,一种办法是在for循环中对返回的键进行排序。为此,可使用函数sorted()来获得按特定顺序排列的键列表的副本:

favorite_languages = { 'jen': 'python', 'sarah': 'c', 'edward': 'ruby', 'phil': 'python', } 
for name in sorted(favorite_languages.keys()):
print(name.title() + ", thank you for taking the poll.")
Edward, thank you for taking the poll.
Jen, thank you for taking the poll.
Phil, thank you for taking the poll.
Sarah, thank you for taking the poll.

遍历所有值

如果你感兴趣的主要是字典包含的值,可使用方法values(),它返回一个值列表,而不包含任何键。例如,如果我们想获得一个这样的列表,即其中只包含被调查者选择的各种语言,而不包含被调查者的名字,可以这样做:

favorite_languages = { 'jen': 'python', 'sarah': 'c', 'edward': 'ruby', 'phil': 'python', } 
print("The following languages have been mentioned:")
for language in favorite_languages.values():
print(language.title())
The following languages have been mentioned:
Python
C
Ruby
Python

这种做法提取字典中所有的值,而没有考虑是否重复。涉及的值很少时,这也许不是问题,但如果被调查者很多,最终的列表可能包含大量的重复项。为剔除重复项,可使用集 合(set)。集合类似于列表,但每个元素都必须是独一无二的:

favorite_languages = { 'jen': 'python', 'sarah': 'c', 'edward': 'ruby', 'phil': 'python', }
print("The following languages have been mentioned:")
for language in set(favorite_languages.values()):
print(language.title())
The following languages have been mentioned:
Ruby
C
Python

通过对包含重复元素的列表调用set() ,可让Python找出列表中独一无二的元素,并使用这些元素来创建一个集合。我们使用了set() 来提取favorite_languages.values() 中不同的语言。

嵌套

可以在列表中嵌套字典、在字典中嵌套列表甚至在字典中嵌套字典。

# 创建一个用于存储外星人的空列表 
aliens = []

# 创建30个绿色的外星人
for alien_number in range(30):
new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
aliens.append(new_alien)

# 显示前五个外星人
for alien in aliens[:5]:
print(alien)
{'color': 'green', 'points': 5, 'speed': 'slow'}
{'color': 'green', 'points': 5, 'speed': 'slow'}
{'color': 'green', 'points': 5, 'speed': 'slow'}
{'color': 'green', 'points': 5, 'speed': 'slow'}
{'color': 'green', 'points': 5, 'speed': 'slow'}

函数

向函数传递信息

def greet_user(username):
"""显示简单的问候语"""
print("Hello, " + username.title() + "!")
greet_user('baikal')
Hello, Baikal!
  • 位置实参
  • 关键字实参
  • 默认值
def describe_pet(animal_type, pet_name):
pass

describe_pet('dog', 'Hello')

describe_pet(pet_name='Hello', animal_type='dog')

def describe_pet(pet_name, animal_type='dog'):
pass

describe_pet('Hello')

返回值

def get_formatted_name(first_name,last_name):
"""返回整洁的姓名"""
full_name = first_name + ' ' + last_name
return full_name.title()

musician = get_formatted_name('jk','brown')
print(musician)
Jk Brown

使得实参可选

有些人有中间名

def get_formatted_name(first_name, last_name, middle_name=''):
"""返回整洁的姓名"""
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):
"""返回一个字典,其中包含有关一个人的信息"""
person = {'first': first_name, 'last': last_name}
return person

musician = build_person('jimi', 'hendrix')
print(musician)
{'first': 'jimi', 'last': 'hendrix'}

在函数定义中,我们新增一个可选形参age ,并将其默认值设置为空字符串。如果函数调用中包含这个形参的值,这个值将存储到字典中。在任何情况下,这个函数都会存储人的姓名,但可对其进行修改,使其也存储有关人的其他信息

def build_person(first_name, last_name, age=''): 
"""返回一个字典,其中包含有关一个人的信息"""
person = {'first': first_name, 'last': last_name}
if age:
person['age'] = age
return person

musician = build_person('jimi', 'hendrix', age=27)
print(musician)
{'first': 'jimi', 'last': 'hendrix', 'age': 27}

传递列表

向函数传递列表很有用,这种列表包含的可能是名字、数字或更复杂的对象(如字典)。将列表传递给函数后,函数就能直接访问其内容。下面使用函数来提高 处理列表的效率。 假设有一个用户列表,我们要问候其中的每位用户。下面的示例将一个名字列表传递给一个名为greet_users() 的函数,这个函数问候列表中的每个人:

def greet_users(names): 
"""向列表中的每位用户都发出简单的问候"""
for name in names:
msg = "Hello, " + name.title() + "!"
print(msg)

usernames = ['hannah', 'ty', 'margot']
greet_users(usernames)
Hello, Hannah!
Hello, Ty!
Hello, Margot!
# 首先创建一个列表,其中包含一些要打印的设计 
unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_designs = []
while unprinted_designs:
current_design = unprinted_designs.pop()

print("Printing model: " + current_design)
completed_designs.append(current_design)

for completed_design in completed_designs:
print(completed_design)
dodecahedron
robot pendant
iphone case

禁止函数修改列表

print_models(unprinted_designs[:], completed_models)

以下方法:

def print_models(unprinted_designs, completed_models): 
""" 模拟打印每个设计,直到没有未打印的设计为止 打印每个设计后,都将其移到列表completed_models中 """
while unprinted_designs:
current_design = unprinted_designs.pop()
# 模拟根据设计制作3D打印模型的过程
print("Printing model: " + current_design)
completed_models.append(current_design)

def show_completed_models(completed_models):
"""显示打印好的所有模型"""
print("\nThe following models have been printed:")
for completed_model in completed_models:
print(completed_model)

unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models = []
print_models(unprinted_designs, completed_models)
show_completed_models(completed_models)
Printing model: dodecahedron
Printing model: robot pendant
Printing model: iphone case

The following models have been printed:
dodecahedron
robot pendant
iphone case

unprinted_designs处理完之后为空

即便打印所有设计后,也要保留原来的未打印的设计列表,以供备案。
可向函数传递列表的副本而不是原件;这样函数所做的任何修改都只影响副本,而丝毫不影响原件。

def print_models(unprinted_designs, completed_models): 
"""
模拟打印每个设计,直到没有未打印的设计为止
打印每个设计后,都将其移到列表completed_models中
"""
while unprinted_designs:
current_design = unprinted_designs.pop()
# 模拟根据设计制作3D打印模型的过程
print("Printing model: " + current_design)
completed_models.append(current_design)

def show_completed_models(completed_models):
"""显示打印好的所有模型"""
print("\nThe following models have been printed:")
for completed_model in completed_models:
print(completed_model)

unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models = []

# 以下为核心
print_models(unprinted_designs[:], completed_models)

show_completed_models(completed_models)
show_completed_models(unprinted_designs)
Printing model: dodecahedron
Printing model: robot pendant
Printing model: iphone case

The following models have been printed:
dodecahedron
robot pendant
iphone case

The following models have been printed:
iphone case
robot pendant
dodecahedron

虽然向函数传递列表的副本可保留原始列表的内容,但除非有充分的理由需要传递副本,否则还是应该将原始列表传递给函数,因为让函数使用现成列表可避免花时间和内存创 建副本,从而提高效率,在处理大型列表时尤其如此。

传递不定数量的实参

def make_pizza(*toppings): 
"""打印顾客点的所有配料"""
print(toppings)

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

形参名*toppings 中的星号让Python创建一个名为toppings 的空元组,并将收到的所有值都封装到这个元组中。函数体内的print语句通过生成输出来证明Python能够处理使用一个值调用函数的情形,也能处理使用三个值来调用函数的情形。它以类似的方式处理不同的调用,注意,Python将实参封装到一个元组中,即便函数只收到一个值也如此

def make_pizza(*toppings): 
"""打印顾客点的所有配料"""
for topping in toppings:
print("- " + topping)

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

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

如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。 例如,如果前面的函数还需要一个表示比萨尺寸的实参,必须将该形参放在形参*toppings 的前面

def make_pizza(size, *toppings): 
"""概述要制作的比萨"""
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

class Dog():
def __init__(self, name, age):
self.name = name
self.age = age

def sit(self):
print(self.name.title() + " is now sitting!")

def roll(self):
print(self.name.title() + " rolled over!")

继承

要编写的类是另一个现成类的特殊版本,可使用继承。一个类继承另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类 ,而新类称为子类。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。

class Car():
'''汽车'''
def __init__(self,make,model,year):
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0

def get_descriptive_name(self):
long_name = str(self.year) + ' ' + self.make + ' ' + self.model
return long_name.title()

def read_odometer(self):
print("This car has " + str(self.odometer_reading) + " miles on it.")

def update_odometer(self, mileage):
if mileage >= self.odometer_reading:
self.odometer_reading = mileage
else:
print("You can't roll back an odometer!")

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

class ElectricCar(Car):
"""电动车"""

def __init__(self, make, model, year):
super().__init__(make, model, year)
self.battery_size = 90

def describe_battery(self):
"""打印一条描述电瓶容量的消息"""
print("This car has a " + str(self.battery_size) + "-kWh battery.")

my_byd = ElectricCar('Song','V1', 2021)
print(my_byd.get_descriptive_name())
2021 Song V1
my_byd.describe_battery()
This car has a 90-kWh battery.

重写父类方法

假设Car类有一个名为fill_gas_tank()的方法,它对全电动汽车来说毫无意义,因此就可能想重写它。

def ElectricCar(Car): 
def __init__(self,make,model,year):
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0

def fill_gas_tank():
"""电动汽车没有油箱"""
print("This car doesn't need a gas tank!")

现在,如果有人对电动汽车调用方法fill_gas_tank() ,Python将忽略Car 类中的方法fill_gas_tank() ,转而运行上述代码。使用继承时,可让子类保留从父类那里继 承而来的精华,并剔除不需要的糟粕。

将实例用作属性(避免类臃肿)

使用代码模拟实物时,类添加的细节越来越多:属性和方法清单以及文件都越来越长。在这种情况下,可能需要将类的一部分作为一个独立的类提取出来。 你可以将大型类拆分成多个协同工作的小类。 例如,不断给ElectricCar 类添加细节时,我们可能会发现其中包含很多专门针对汽车电瓶的属性和方法。在这种情况下,我们可将这些属性和方法提取出来,放到另一个名 为Battery 的类中,并将一个Battery 实例用作ElectricCar 类的一个属性:

class Car():
'''汽车'''
def __init__(self,make,model,year):
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0

def get_descriptive_name(self):
long_name = str(self.year) + ' ' + self.make + ' ' + self.model
return long_name.title()

def read_odometer(self):
print("This car has " + str(self.odometer_reading) + " miles on it.")

def update_odometer(self, mileage):
if mileage >= self.odometer_reading:
self.odometer_reading = mileage
else:
print("You can't roll back an odometer!")

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


class Battery():
'''电瓶'''
def __init__(self, battery_size=70):
self.battery_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()

my_byd = ElectricCar('Tang', 'V2', 2018)
print(my_byd.get_descriptive_name())
2018 Tang V2
my_byd.battery.describe_battery()
This car has a 70-kWh battery.

Python标准库

collections 中的一个类——OrderedDict 。 字典让你能够将信息关联起来,但它们不记录你添加键—值对的顺序。要创建字典并记录其中的键—值对的添加顺序,可使用模块collections 中的OrderedDict 类。OrderedDict 实例的行为几乎与字典相同,区别只在于记录了键—值对的添加顺序

from collections import OrderedDict 
favorite_languages = OrderedDict()
favorite_languages['jen'] = 'python'
favorite_languages['sarah'] = 'c'
favorite_languages['edward'] = 'ruby'
favorite_languages['phil'] = 'python'
for name, language in favorite_languages.items():
print(name.title() + "'s favorite language is " + language.title() + ".")
Jen's favorite language is Python.
Sarah's favorite language is C.
Edward's favorite language is Ruby.
Phil's favorite language is Python.

它兼具列表和字典的主要优点(在将信息关联起来的同时保留原来的顺序)。等你开始对关心的现实情形建模时,可能会发现有序字典正好能够满足需 求。随着你对标准库的了解越来越深入,将熟悉大量可帮助你处理常见情形的模块。

类编码风格

在编写的程序较复杂时尤其如此。

类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线。

实例名和模块名都采用小写格式,并在单词之间加上下划线。

对于每个类,都应紧跟在类定义后面包含一个文档字符串。

这种文档字符串简要地描述类的功能,并遵循编写函数的文档字符串时采用的格式约定。

每个模块也都应包含一个文 档字符串,对其中的类可用于做什么进行描述。

可使用空行来组织代码,但不要滥用。

在类中,可使用一个空行来分隔方法;而在模块中,可使用两个空行来分隔类。

需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的import语句,再添加一个空行,然后编写导入你自己编写的模块的import语句。

在包含多条import 语句的程序中,这种做法让人更容易明白程序使用的各个模块都来自何方。

文件和异常

从文件中读数据

读取整个文件

with open('pi_digits.txt') as file_object:
contents = file_object.read()
print(contents+'-')
3.1415926
9981774966363515
1776363514966363516363981774966-

也可以调用open()和close() 来打开和关闭文件,但这样做时,如果程序存在bug,导致close()语句未执行,文件将不会关闭。

最好的方法是:让Python去确定,coder只管打开文件,并在需要时使用它,Python自会在合适的时候自动将其关闭

相比于原始文件,该输出唯一不同的地方是末尾多了一个空行。为何会多出这个空行呢?因为read() 到达文件末尾时返回一个空字符串,而将这个空字符串显示出来时就是一 个空行。要删除多出来的空行,可在print 语句中使用rstrip() :

with open('pi_digits.txt') as file_object: 
contents = file_object.read()
print(contents.rstrip())
3.1415926
9981774966363515
1776363514966363516363981774966
with open('pi_digits.txt') as fp:
for f in fp:
print(f.rstrip())
3.1415926
9981774966363515
1776363514966363516363981774966
with open('pi_digits.txt') as fp:
lines = fp.readlines()

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

print(pi_string)
print(len(pi_string))
3.141592699817749663635151776363514966363516363981774966
56
with open('pi_digits.txt') as fp:
lines = fp.readlines()

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

print(pi_string)
3.141592699817749663635151776363514966363516363981774966

写入文件

参数’a’——添加到文件末尾

filename = 'programming.txt' 
with open(filename, 'a') 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")

异常

print(5/0)
---------------------------------------------------------------------------

ZeroDivisionError                         Traceback (most recent call last)

<ipython-input-217-fad870a50e27> in <module>
----> 1 print(5/0)


ZeroDivisionError: division by zero
filename = 'alice.txt'
try:
with open(filename) as f_obj:
contents = f_obj.read()
except FileNotFoundError:
msg = "Sorry, the file " + filename + " does not exist."
print(msg)
Sorry, the file alice.txt does not exist.

分析文本

  1. 提取文本

下面来提取童话 Alicein Wonderland 的文本,并尝试计算它包含多少个单词。我们将使用方法split(),它根据一个字符串创建一个单词列表。下面是对只包含童话名”Alice in Wonderland” 的字符串调用方法split()的结果:

title = ' Alice in Wonderland'
title.split()
['Alice', 'in', 'Wonderland']
def count_words(filename):
'''计算一个文件有多少个单词'''
try:
with open(filename) as fn:
contents = fn.read()
except FileNotFoundError:
# pass
msg = "Sorry,the file " + filename + " not found!"
print(msg)
else:
words = contents.split()
num_words = len(words)
print("The file " + filename + " has about " + str(num_words) + " words")

filename = 'programming.txt'
count_words(filename)





The file programming.txt has about 18 words

存储数据

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

import json
numbers = [2,4,5,73,24,563,21,56,334,54]
filename = 'numbers.json'
with open(filename,'w') as fn:
json.dump(numbers,fn)
import json

filename = 'numbers.json'
with open(filename) as fn:
numbers = json.load(fn)

print(numbers)
[2, 4, 5, 73, 24, 563, 21, 56, 334, 54]

重构

代码能够正确地运行,但可做进一步的改进——将代码划分为一系列完成具体工作的函数。这样的过程被称为重构。

核心:一个函数 完成一个功能

内置函数

map()

map() 会根据提供的函数对指定序列做映射。

第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。

>>> def square(x) :         # 计算平方数
... return x ** 2
...
>>> map(square, [1,2,3,4,5]) # 计算列表各个元素的平方
<map object at 0x100d3d550> # 返回迭代器
>>> list(map(square, [1,2,3,4,5])) # 使用 list() 转换为列表
[1, 4, 9, 16, 25]
>>> list(map(lambda x: x ** 2, [1, 2, 3, 4, 5])) # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]

zip()

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表

>>> a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b) # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c) # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> zip(*zipped) # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
[(1, 2, 3), (4, 5, 6)]

全文代码及内容主要基于《Python编程:从入门到实践》
下载链接: https://pan.baidu.com/s/1r2JJb7HB-OSxUxqZBdNotg 密码:fkw5

若文件失效请联系我更新