自学Python之Python基础:(三)Python代码结构

转载的老板请注明出处:http://blog.csdn.net/cc_xz/article/details/78688691万分感谢!

在本篇中,你将了解到:
1.关于Python注释的方式。
2.Python中的条件判断:if。
3.使用while进行循环。
4.使用for实现推导式。
5.Python中的各种参数说明。
6.Python中的生成器。
6.在Python中对异常进行捕获。


注释:
注释是程序在运行过程中会被Python解释器忽略的一段文字,通过注释,可以解释和明确Python代码的功能,记录将来要修改的地方等等。在Python中使用“#”字符表示注释,在从“#”开始到当前行结束的部分中的内容都是注释,既可以把注释作为单独的一行代码,也可以将注释和代码放在一起。

print("这是一行代码") #这是一行注释。 
#这也是一行注释。 
''' 这是一个多行注释的代码 
比如这样  
还有这样!'''


使用if、elif和else进行比较:

boole = True 
if boole:
   print("如果结果是True,则显示这个")
else: 
   print("如果结果是False,则显示这个")

输出结果为:

如果结果是True,则显示这个

在上述代码中,首先判断一个布尔值的变量,然后根据判断的结果执行相应的代码。在程序中,if和else两行是Python用来声明判断条件的。而判断的内容则是boole这个变量,如果它的值(如果不是布尔值,则通过计算等操作得出一个布尔值)为True,则执行第一个代码块中的内容,反之如果结果为False,则执行第二个代码块中的内容。

在Python中,是由缩进决定了if和else是如何匹配的。

boole01 = True
bolle02 = True

if boole01:
   if bolle02:
      print("如果两个值都为True,则执行这行代码。")
   else:
      print("如果boole01为True,boole02为False,则执行这行代码。")
else:
   if bolle02:
      print("如果boole01为False,boole02为True,则执行这行代码。")
   else:
      print("如果两个值都为False,则执行这行代码。") 

输出结果为:

如果两个值都为True,则执行这行代码。

判断多个条件:
如果要判断的条件超过两个,则可以添加多个elif。

boole01 = False
bolle02 = False

if boole01 == True:
   print("如果结果是True")
elif bolle02 == False:
   print("如果boole02结果是False")
else:
   print("如果上述条件判断没有符合具体情况时")

输出结果为:

如果boole02结果是False


Python常见操作符:

含义 符号
相等 ==
不等于 !=
小于 <
小于等于 <=
大于 >
大于等于 >=
X 属于 XX X in XX
and
or
not

其中:

  • and运算符是“与”,只有所有的结果都是True时,使用and运算出的结果才能是True。
  • or运算符是“或”,当多个结果中有一个True时,使用or运算出的结果就是True。
  • not运算符是“非”,它是单目运算符(不能比较多个公式),它可以把True变成False,同时也用于将False变成True。

另外,上述这些操作符,在判断公式中,都会返回布尔值的True或False。而且,两个等于号(==)用来判断是否相等,一个等于号(=)是将某个值赋给变量。如果需要多重比较,则可以使用布尔操作符连接表达式,以决定最终的布尔值。


什么是真(True)值:
如果表达式返回的类型不是布尔值,那么Python应该将什么样的返回值认定是True或False?以下情况全部会被编译器认为结果是False。

含义 符号
布尔值 False
null类型 None
整型 0
浮点型 0.0
字符串(空) “”
空列表 [ ]
空元组 ( )
空字典 { }
空集合 set( )

剩下的元素都将被认为是真(True)。


使用while进行循环:
使用if、elif、else等判断条件都是自顶部向下执行,但有时需要一些重复的操作,循环。在Python中最简单的循环机制是while。

使用break跳出循环:
如果希望让循环在某个条件下才停止循环,但又不确定是在哪次跳出,则可以在无限循环中使用break关键字。例如:

while True: 
   string = input("请输入字符,当字符全部内容为“哈哈”时跳出循环") 
   if string == "哈哈": 
      break  
print("循环结束")

输出结果为:

请输入字符,当字符全部内容为“哈哈”时跳出循环 嘿嘿
请输入字符,当字符全部内容为“哈哈”时跳出循环 呵呵
请输入字符,当字符全部内容为“哈哈”时跳出循环 哈哈
循环结束


使用continue跳到循环开始:
有时候并不需要结束整个循环,而只是希望直接开始下一轮循环的开始。

while True:
   value = input("请输入一个整数,如果是偶数则跳过,如果是奇数则计算出它的平方,输入Q结束循环。")
   if value == "Q":  # 如果输入结果为Q,则跳出循环。
      break
   number = int(value)  # 将输入的str字符串转化为整数。如果输入非数字则报异常。
   if number % 2 == 0:  # 通过求余来判断奇偶数。 
      print("这是一个偶数")
      continue  # 如果结果是偶数,则继续循环。
   print("这个数字是奇数,它的平方为:", number * number)
print("循环结束") 

输出结果为:

请输入一个整数,如果是偶数则跳过,如果是奇数则计算出它的平方,输入Q结束循环。10
这是一个偶数
请输入一个整数,如果是偶数则跳过,如果是奇数则计算出它的平方,输入Q结束循环。9    
这个数字是奇数,它的平方为: 81
请输入一个整数,如果是偶数则跳过,如果是奇数则计算出它的平方,输入Q结束循环。Q    
循环结束


在循环外使用else:
如果在while循环正常结束,并没有使用break跳出的情况下,程序将进入到可选的else代码块中。案例如下:

numbers = [1, 3, 5, 7, 9]
position = 0

while position < len(numbers):  # 如果列表不为空,则执行循环。  
   number = numbers[position]
   if number % 2 == 0:
      print("该数是一个偶数,值为:", number)
      break
   position += 1
else:  # 如果没有被break强制跳出,则执行else中的代码。
   print("没有发现偶数。")

print("循环结束")


使用for迭代:
Python频繁的使用迭代器,它允许在数据结构长度未知和具体实现方式的情况下遍历整个数据结构,并且支持迭代快速读写中的数据,以及允许处理不能一次性读入计算机内存的数据流的处理。

numbers = [1, 3, 5, 7, 9]
for number in numbers:
   print("迭代列表的结果为::", number)

words = "word"
for word in words:
   print("迭代字符串的结果为:", word)

dicts = {"A": 1, "B": 2, "C": 3}
# dicts.items()表示迭代字典中的Key和Value,同理可以分别使用.keys()和.values()
for MyDict in dicts.items():
   print("迭代字典的结果为:", MyDict)

输出结果为:

迭代列表的结果为:: 1
迭代列表的结果为:: 3
迭代列表的结果为:: 5
迭代列表的结果为:: 7
迭代列表的结果为:: 9
迭代字符串的结果为: w
迭代字符串的结果为: o
迭代字符串的结果为: r
迭代字符串的结果为: d
迭代字典的结果为: ('A', 1)
迭代字典的结果为: ('B', 2)  
迭代字典的结果为: ('C', 3)


推导式:
推导式是从一个或多个迭代器快速而简洁的创建数据结构的一种方法。它可以将循环和条件判断相结合,从而避免语法的冗长。


列表推导式:

number_list = [number for number in range(1,14)] 
print(number_list)

输出结果为:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

这是一个非常具有Python风格创建列表方式的“列表推导”。
上述案例中,有两个number,实际上,是先创建第二个number,即:在列表中创建一个for循环,通过range()函数作为条件,然后将每次执行的结果(输出的值)赋值给第二个number。但这个过程中,输出的值只是应用在for循环中。而为了将输出结果赋值给list列表,所以在for循环之外,调用number这个变量。


求奇偶数:

number_list = [number for number in range(1,14) if number % 2 == 1] 
print(number_list)

输出结果为:

[1, 3, 5, 7, 9, 11, 13]

在上述代码的基础上,在推导式中加入一个if判断,当number的结果(从1至13)如果除以2时,如果有余数,并且余数等于1时,才将number的值加入到number_list中。
值得注意的是,“%”是求余符,在“%”执行时,会将 被除数 除 2(代码中指定的是2),但得出的结果并不是商,而是余数。
而如果使用传统的方法,则代码如下:

number_list2 = []
for number in range(1,14): 
   if number % 2 == 1: 
      number_list2.append(number) 
print(number_list2)

当然对应的,使用传统方法可能更容易理解,但使用推导式会使代码更加简洁。


推导式创建元组:
由于元组是在创建后便无法修改的,所以必须在创建时就使其拥有所有的数据。除了可以使用tuple()函数将一个或多个列表转换为元组的值外,还可以通过推导式创建元组。

rows = range(1,6)  
cols = range(1,4)  
cells = [tuple(rows),tuple(cols)] 
print(cells)

输出结果为:

[(1, 2, 3, 4, 5), (1, 2, 3)]    

但是由于元组必须一次性创建,所以直接转换的方式无法创建出“单元格”,只能被动的将列表中的数据转换为元组的值,并且当我们希望对列表中的值进行筛选时,也无法做到。
请看使用推导式创建元组:

cells2 = [(row,col) for row in rows if row != 4 for col in cols] 
print(cells2)

输出结果为:

[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3), (5, 1), (5, 2), (5, 3)]

我们不但使用for同时遍历了rows和cols两个列表中的数据,并且根据我们希望的方式,将遍历的结果通过row和col组成了一个个类似坐标的数据。同时,在遍历rows时,还可以通过if判断,过滤掉我们不希望出现的第4行的数据。


函数:
如果我们希望复用代码,就需要把代码组织成可管理、调用的代码段,代码复用的第一步就是使用函数,通过对其命名来区分其他的代码段。函数可以接受任何数据或其他类型的输入作为参数,并返回数字或其他类型的结果。

def do_nothing(): 
   pass

这便是一个最简单的Python函数,即使对于一个没有参数的函数,仍然需要在定义时加上圆括号和冒号。并且函数中的代码要像if和for等需要通过缩进来表示他们是一体的。在Python的函数中使用pass作为占位符,表示该函数中没有任何代码(实际上pass也执行了跳过的操作)。
下面是函数一些简单的应用:

def do_nothing():
   print("这是一个函数,你可以使用它进行一些操作")
   return 10
if do_nothing():
   print("如果这个函数返回了一个值,则显示这条语句。")
else:
   print("如果这个函数没有返回任何值,则显示这条语句。")

输出结果为:

这是一个函数,你可以使用它进行一些操作
如果这个函数返回了一个值,则显示这条语句。


使用函数的参数:

def do_test(string):
   print("接收到的参数为:", string)
do_test("这是一段测试")

输出结果为:

接收到的参数为: 这是一段测试 

传入到函数的值就被称为参数。当调用包含参数的函数时,需要显式的指定对应的参数,而这些值会被复制到函数中对应的参数中。一个函数可以接受任何数量和任何类型的值作为输入的参数。并且可以返回任何数量和任何类型的结果。如果函数中没有显式的调用return函数(返回某数据),Python则会默认返回None。


位置参数:
下面创建一个带有位置参数的函数,并返回一个字典:

def do_test(wine, entree, dessert):
   return {"wine": wine, "entree": entree, "dessert": dessert}
print(do_test("wine", "entree", "dessert"))

输出结果为:

{'wine': 'wine', 'dessert': 'dessert', 'entree': 'entree'}

这种方式使用的很多,但其弊端是必须熟记每个位置的参数的含义,在调用该函数时,如果把参数的位置搞混,那么得到的结果将是截然不同的。


关键字参数:
为了避免位置参数所带来的混乱,在调用参数时可以指定对应的参数名称,甚至可以采用与函数中参数定义的顺序所不同的顺序调用。

def do_test(wine, entree, dessert):
   return {"wine": wine, "entree": entree, "dessert": dessert}
print(do_test('wine', entree="entree", dessert="dessert"))

输出结果为:

{'entree': 'entree', 'dessert': 'dessert', 'wine': 'wine'}

如果位置参数和关键字参数同时出现,则优先考虑位置参数。并且,如果第一个参数就定义成关键字参数,那么后续所有的参数都必须是关键字参数。


指定默认参数:
当调用方没有提供对应的参数时,可以在函数中指定默认参数,而默认参数的值是在函数被定义时就已经确定好的,而不是在程序运行时。并且,如果可以,就布要将一个可变的数据类型(列表或字典)作为默认参数值。

def do_test(wine, entree, dessert='dessert'):
   return {"wine": wine, "entree": entree, "dessert": dessert}
print(do_test('wine', entree="entree"))

输出结果为:

{'wine': 'wine', 'entree': 'entree', 'dessert': 'dessert'}

在上述案例中,如果你提供了默认参数的参数时,在调用时,函数就会使用你所提供的值来运行。


使用“ * ”收集位置参数:
当参数被用在函数内部时,使用星号可以将一组可变数量的位置参数组合成一个元组。例如:

def do_test(*my_tuple):
   return my_tuple
print(do_test(1, 2, 3, 4, 5, 6))

输出结果为:

(1, 2, 3, 4, 5, 6)

这种使用方法,同print()一样可接受任意数量的参数,而如果在函数中同时指定了位置参数,那么“ * ”将收集多余的参数。

def do_test(param, param01, *my_tuple):
   print("第一个参数是:", param, "--- 第二个参数是:", param01, "--- 剩下的参数是:", my_tuple)
do_test(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

输出结果为:

第一个参数是: 1 --- 第二个参数是: 2 --- 剩下的参数是: (3, 4, 5, 6, 7, 8, 9, 10)

但值得注意的是,使用“ * ”的位置参数必须放在参数的末端。


使用“* * ”收集关键字参数:
在使用两个星号可以将参数收集到一个字典中,参数的名称是字典的键,对应的参数值是字典的值。

def do_test(**my_dict): 
   print(my_dict) 
do_test(A="1",B="2",C="3")

输出结果为:

{'B': '2', 'A': '1', 'C': '3'}

如果一个函数中,既包含“ * ”又包括“ ** ”,那么它们会按照顺序来解析。


函数:
你可以将一个函数(返回值)赋值给变量,也可以将函数(返回值)作为参数被其他函数调用。

def answer():
   print("Test")
def do_test(func):
   func()
do_test(answer)

输出结果为:

Test


值得注意的是,在调用do_test()时,输入的参数是answer,而不是answer()。在Python中使用圆括号意味着调用函数,而在没有圆括号的情况下,Python会将函数作为一个普通的对象。
下面是一个带参数的案例:

def add_args(arg1, arg2):
   print(arg1 + arg2)
def run_args(func, arg1, arg2):
   func(arg1, arg2)
run_args(add_args, 5, 10)  

输出结果为:

15

在run_args()函数中,在调用时的add_args参数被赋值给func,而5和10分别赋值给arg1和arg2。而在执行run_args()时,实际上执行的是:add_args(5, 10)


生成器:
生成器是用来创建Python序列的对象,在创建序列时,无需在内存中创建和存储整个序列。通常,生成器是为迭代器产生数据的,例如range()。当每次迭代生成数据时,它会记录上次调用的位置,并返回下一个值。这点和普通函数不一样,一般的函数都不会记录前一次的调用位置。而且每次都会在函数的第一行开始执行。
如果你希望创建一个比较大的序列,使用推导式的代码会很长,这时便可以尝试写一个生成器函数。生成器函数和普通函数类似,但是它的返回值使用yield语句声明而不是return。

def my_range(first=0, last=10, step=1):
   number = first
   while number < last:
      yield number
      number += step
print(my_range(0, 8))  # 默认返回生成器对象,无法正常显示。需要使用循环对生成器对象进行迭代。
for x in my_range(0, 8):
   print(x)

输出结果为:

object my_range at 0x0000000000D13BA0>
0 1 2 3 4 5 6 7    (此处手动排序)


使用try和except处理异常:
在异常可能发生的地方添加处理异常的代码,对于明确错误是非常有效的方法,即使不会立刻解决问题,至少程序会记录当前的运行环境并且停止程序的执行。如果发生在某些函数中的异常不能被立刻捕捉,那么它将带来隐患,直到被某个调用该函数的异常处理程序所捕获。在程序没有提供对应的异常捕获时,Python会输出错误消息和关于错误发生处的信息,然后终止程序。

my_list = [1,2,3,4] 
position = 10 
try: 
   my_list[position] 
except: 
   print("这是由于列表的索引超出列表长度所导致的问题。")
   print("列表长度为:",len(my_list))
   print("索引值为:",position)
else: #当程序没有发生异常,将执行else作用域中的代码。
   print("程序没有引发任何异常")

输出结果为:

这是由于列表的索引超出列表长度所导致的问题。                                                                                                                                                                                                      
列表长度为: 4    
索引值为: 10

在上述代码中,会执行try作用域中的代码,如果执行中出现错误,那么就会抛出异常,即:执行except作用域中的代码。否则程序将跳过except作用域。
在上述案例中,一个无参的except适用于任何类型的异常。但往往程序中会发生多种类型的异常,所以最好分开并针对可能发生的异常类型进行针对性处理。


针对性的异常捕获:

my_list = [1,2,3,4] 
while True: 
   value = input("请输入列表的索引以查看列表。(按q退出)")
   if value == "q": 
      break
   try:
      position = int(value)
      print("列表中的值为:",my_list[position])
   except IndexError as error:
      print("索引值错误",position)
   except Exception as other: 
      print("其他异常:", other)

输出结果为:

请输入列表的索引以查看列表。(按q退出)d
其他异常: invalid literal for int() with base 10: 'd'
请输入列表的索引以查看列表。(按q退出)2
列表中的值为: 3
请输入列表的索引以查看列表。(按q退出)6
索引值错误 6
请输入列表的索引以查看列表。(按q退出)

你可能感兴趣的:(自学之路之Python基础)