深度学习之 Python3基础

总览

hello world

python3是面向对象编程语言,和初学c语言一样,先从hello world开始。

#!/usr/local/bin/python3
# Copyright 2022 shichaog

print('Hello, World.')

以#!开始的第一行被称为Shebang行,一般作为文本文件的第一行出现,表示执行该脚本文件的默认解释器。其下图显示了其作用。
请添加图片描述
第一行的报错是没有#!开始行,而第二行则是上面完整程序片段运行结果,在很多脚本程序中都有该Shebang行,如shell等。第二行的# Copyright 2022 shichaog是注释行,第三行则是hello world主体,print(‘Hello, World.’),相比于c语言,简单很多。
python版本众多,获取python版本内置方法如下:

#!/usr/local/bin/python3
# Copyright 2022 shichaog
import platform

print('This is python version {}'.format(platform.python_version()))

输出如下:
This is python version 3.7.2

其输出是python的版本信息。该系列所有python脚本均基于该版本。

main函数

和c语言一样,python也可以有main函数作为主函数,稍微复杂一些的python工程都会使用main函数,比如数据分析、深度学习等。python一个main函数的例子如下:

  1 #!/usr/local/bin/python3
  2 # Copyright 2022 shichaog
  3
  4 import platform
  5
  6 def main():
  7     message()
  8
  9 def message():
 10     print('This is python version {}'.format(platform.python_version()))
 11
 12 if __name__ == '__main__': main()

该代码片段的作用和上一节一样,都是打印python版本信息,但是多了main函数,main函数调用了message函数,在message函数中打印了版本信息。第十二行的条件语句调用main将使得python解释器会先读入所有的脚本,然后在执行。为每个python文件编写main函数是个好习惯,python中的函数需要先定义在调用,有了main之后解释器先读入整个脚本自然在运行main的时候可以找到message函数。此外main使得写出来的模块可以在别的地方或者本身进行执行使用。在”if name == ‘main‘“中加入一些调试代码,可以让外部模块调用的时候不执行我们的调试代码,但是如果我们想排查问题的时候,直接执行该模块文件,调试代码能够正常运行,这样非常方便。

表达式和语句

python代码有表达式和语句组成,并由python解释器执行。它们的主要区别是“表达式”是一个值,它的结果一定是一个Python对象。当Python解释器计算它时结果可以是任何对象。结果不是对象的代码则成为‘语句’。它们表示的是一个动作而不是生成或者返回一个值。
表达式只包含标识符、文本和运算符,其中运算符包括算术和布尔运算符、函数调用运算符()、订阅运算符[]等,并且可以简化为某种"值",可以是任何python对象。语句则包含print、if/else、for、while、yeild等。
表达式的一些例子如:

x=y
x*y
(x,y)
x
True
f()

上述式子的特点最终结果都是“值”对象。前面打印python版本的代码片段则是语句的例子。

空格和注释

和许多脚本语言不同,空格在python中是比较重要的。python的代码块由缩进分隔,没有c语言中的括号,大括号之类的代码块标记。缩进有助于代码阅读和编写。

#!/usr/local/bin/python3
# Copyright 2022 shichaog

import platform

def main():
    message()

def message():
    print('This is python version {}'.format(platform.python_version()))
    print("line 2") # this is a comment
    print("line3")

if __name__ == '__main__': main()

上面的代码增加了message函数主体,三行print缩进都是对齐的,当不对齐时,运行改脚本解释器就会报错。报错信息是IndentationError: unindent does not match any outer indentation level,当然如果print(“line3”)顶格也不会报错,这是因为解释器认为改语句并不属于message函数了。
python中注释是以#开头的,其可以是独立一行或者在代码行之后,如上面代码片段中的#this is a comment。

条件

#!/usr/local/bin/python3
# Copyright 2022 shichaog

x = 13
y = 13

if x < y:
    print('x < y: x is {} and y is {}'.format(x, y))
elif x == y:
    print('x == y: x is {} and y is {}'.format(x, y))
else:
    print('x > y: x is {} and y is {}'.format(x, y))

python中使用if条件语句关键词,elif和else都是条件语句的关键词。上述的代码中xy,也可以写成x13之类的语句。

循环

循环有while和for两种语句。

#!/usr/local/bin/python3
# Copyright 2022 shichaog

words = ['1', '2', '3', '4', '5']
print('while loop results:')
n = 0
while(n < 5):
    print(words[n])
    n += 1

print('for loop results:')
for i in words:
    print(i)

上述两种循环均会打印出1,2,3,4,5这五个值。

函数

#!/usr/local/bin/python3
# Copyright 2022 shichaog

def function(n=1):

    print("return :",n)
    return n

ret = function(13)
print(ret)
ret = function()
print(ret)

#输出结果
return : 13
13
return : 1
1

函数可以有参数和返回值,其中参数可以有缺省值,第二个函数调用时没有传参,这是默认值1起作用,而第一个函数传递了参数13,则会替换掉缺省值。python中所有函数都有返回值,在没有显示调用return语句时,函数的返回值是None(表示没有返回值)。

#!/usr/local/bin/python3
# Copyright 2022 shichaog

class Student:
    stu_name = 'shichaog'
    stu_ID = '13'
    stu_gender = 'female'

    def Name(self):
        print('student name method {}'.format(self.stu_name))
    def ID(self):
        print('Student ID method {}'.format(self.stu_ID))
    def gender(self):
        print('Male {}'.format(self.stu_gender))

def main():
    student = Student()
    student.Name()
    student.ID()
    student.gender()

if __name__ == '__main__': main()

输出结果
student name method shichaog
Student ID method 13
Male female

上述代码中Student是一个类,其有三个成员,三个方法分别获取三个成员值,调用的方法在main函数的代码段部分,这会用在大型的工程中,比如会将自然语言处理抽象成一个类。

类型和值

在python3中所有类型都是class,如下的内置类型所示。

#!/usr/local/bin/python3
# Copyright 2022 shichaog

x = 13
print('x is {}'.format(x))
print(type(x))

x = 13.0
print('x is {}'.format(x))
print(type(x))

x = '''
thirteen
''' # equal to x = 'thirteen'
print('x is {}'.format(x))
print(type(x))

x = [ 1, 2, 3, 4, 5 ]
print('x is {}'.format(x))
print(type(x))

输出如下:
x is 13
<class 'int'>
x is 13.0
<class 'float'>
x is thirteen
<class 'str'>
x is [1, 2, 3, 4, 5]
<class 'list'>

布尔值

布尔值用于逻辑表达式中,

#!/usr/local/bin/python3
# Copyright 2022 shichaog

x = True
print('x is {}'.format(x))
print(type(x))

x = 13 > 10
print('x is {}'.format(x))
print(type(x))
if x:
    print('True')
elif x == 13:
    print('x == 13')
else:
    print('False')

#运行结果
x is True
<class 'bool'>
x is True
<class 'bool'>
True

条件

python3中条件语句是if/elif/else见上小节代码片段,条件运算符包括比较运算符、逻辑运算符和标识运算法

比较运算符作用
==等于
!=不等于
<小于
>大于
<=小于等于
>=大于等于
逻辑运算符作用
and
or
not
标识运算符用例作用
isx is yx和y是相同对象时值true
is notx is not yx和y是不同对象时值true

条件赋值时常用的一种赋值方式

#!/usr/local/bin/python3
# Copyright 2022 shichaog

x = 123 if True else 321
print(x)
x = 123 if False else 321
print(x)
输出为:
123
321

这里的True和False可以时上述运算符得到的结果。

运算符

数学运算符

数学运算符 符号作用
+
-
*乘法
/
//整数除法
%求余数
**指数
-
*乘法
/
-一元负数
+一元整数

比特位运算法

比特运算符 符号作用
&
|
^异与
<<左移
>>右移

比较运算符

条件语句时已经提过。

比较运算符 符号作用
<小于
>大于
<=小于等于
>=大于等于
==等于
!=不等于

布尔运算符

布尔运算符 符号作用
and
or
not
in值在集合中
not in值不在集合中
is对象是同一个
is not对象是不同的

函数

函数是python中可重用代码的基本单元,在上面的函数代码例子中有如下代码段

  1 #!/usr/local/bin/python3
  2 # Copyright 2022 shichaog
  3
  4 import platform
  5
  6 def main():
  7     message()
  8
  9 def message():
 10     print('This is python version {}'.format(platform.python_version()))
 11
 12 if __name__ == '__main__': main()

第12行冒号之后是main函数,冒号之前的if语句中__name__是python内置的特殊变量,该变量将返回执行模块的名字,所有当该文件被其它执行单元用import语句引用的时候,该文件将会以模块的方式运行,__name__名字将是import模块的名字,当该文件没有被其它单元import而单独运行时,__name__的值将等于’main’,此外函数还可以有参数和返回值。

函数参数

有四种传递方式,

fun1(a,b,c)
fun2(a=1,b=2,c=3)
fun3(*args)
fun4(**kargs)

第一种 fun1(a,b,c)是直接将实参赋予行参,根据位置做匹配,即严格要求实参的数量与行参的数量位置相等,比较一般,大多数语言常用这种方式。
第二种 fun2(a=1,b=2,c=3)根据键值对的形式做实参与行参的匹配,通过这种式就可以忽略了参数的位置关系,直接根据关键字来进行赋值,同时该种传参方式还有个好处就是可以在调用函数的时候作为个别选填项,不要求数量上的相等,即可以fun5(3,4)来调用fun2函数,这里关键就是前面的3,4覆盖了原来a、b两个行参的值,但c还是不变采用原来的默认值3,这种模式相较第一种更加灵活,不仅可以通过fun6(c=5,a=2,b=7)来打乱行参的位置,而且可以在但没有对应行参传递的时候常用定义函数时的默认值。
第三种 fun3(*args),这传参方式是可以传入任意个参数,这些若干参数都被放到了tuple元组中赋值给行参args,之后要在函数中使用这些行参,直接操作args这个tuple元组就可以了,这样的好处是在参数的数量上没有了限制,但是因为是tuple,其本身还是有次序的,这就仍然存在一定的束缚,在对参数操作上也会有一些不便。
第四种 fun4(**kargs)最为灵活,其是以键值对字典的形式向函数传参,含有第二种位置的灵活的同时具有第三种方式的数量上的无限制。此外第三四种函数声明的方式前的’*‘,与c里面的指针声明一样,这里仅做声明标识之用
最后要强调的是四种传递方式混合使用(大多数情况是这种),fun7(a,b,*c,**d),但四种方式混用时要遵守:

args = 须在args之后
*args须在args=value之后
**kargs须在*args之后
#!/usr/local/bin/python3
# Copyright 2022 shichaog
def main():
    test(1)
    test(1,2)
    test(1,2,3)
    test(1,2,3,4)
    test(x=1)
    test(x=1,y=2)
    test(x=1,y=2,a=3)
    test(1,y=2)
    test(1, 2, 3, 4, a=1)
    test(1, 2, 3, 4, k=1, t=2, o=3)

def test(x, y=1, *a, **args):
    print (x, y, a, args)

if __name__ == '__main__': main()

输出如下:
1 1 () {}
1 2 () {}
1 2 (3,) {}
1 2 (3, 4) {}
1 1 () {}
1 2 () {}
1 2 () {'a': 3}
1 2 () {}
1 2 (3, 4) {'a': 1}
1 2 (3, 4) {'k': 1, 't': 2, 'o': 3}

返回值

返回值类型非常灵活,可以是简单值也可以是复杂值,也是可以是list、tuple或者dict等等,Python 函数通过调用 return 语句来返回结果。使用 return value 可以返回单个值,用 return value1, value2 则能让函数同时返回多个值。如果一个函数体内没有任何 return 语句,那么这个函数的返回值默认为 None。

函数装饰器

装饰器(Decorators)是 Python 的一个重要部分。简单地说:他们是修改其他函数的功能的函数。在python中所有都是对象,函数也是对象。装饰器是元编程的一种形式,可以描述为返回包装器函数的特殊类型的函数。

#!/usr/local/bin/python3
# Copyright 2022 shichaog
def f1(a_func):
    print("in f1")
    def f2():
        print("before a_func")
        a_func() #调用作为参数传递过来的函数
        print("after a_func")
    return f2

def f3():
    print("in f3")

f3()
print("-----")
x=f1(f3) #函数也是对象,这里将f3作为参数传递给f1,同时返回该函数的执行结果,即f2(对象)给x
x() #调用x所指对象的函数,从输出可以看到f2函数内部调用的函数为f3。
print("=====")
f3=f1(f3)#这里是将x替换为f3,这是f3将被重载,下一行调用f3是输出将和最开始调用f3的结果不一致了。这一语法被称为装饰器
f3()

@f1 #f1函数会被执行,@是装饰器修饰符,作用和范数的赋值类似,@f1起的作用和上面两行类似,是标准的装饰器语法。后面调用f4()的除和前面的类似。
def f4():
    print("in f4")
print("+++++++++")
f4()

输出为:
in f3
-----
before a_func
in f3
after a_func
=====
before a_func
in f3
after a_func
+++++++++
before a_func
in f4
after a_func

函数装饰器里有关键字@wrap,@wraps接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。装饰器在一些大型工程中经常会使用到,比如授权

#!/usr/local/bin/python3
# Copyright 2022 shichaog
from functools import wraps
 
def requires_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth = request.authorization
        if not auth or not check_auth(auth.username, auth.password):
            authenticate()
        return f(*args, **kwargs)
    return decorated

又比如在TensorFlow中,使用装饰器解决环境依赖测试的代码如下:

def run(f):
  with Context() as context:
    register_mhlo_dialect(context)
    f()
  return f


@run
def test_scatter_dimension_numbers():
  """Check that ScatterDimensionNumbers attributes is available and usable."""

  attr = ScatterDimensionNumbers.get(
      update_window_dims=[1, 2, 3],
      inserted_window_dims=[4, 6],
      scattered_dims_to_operand_dims=[6, 7],
      index_vector_dim=8)
  assert attr is not None
  assert str(attr) == ("#mhlo.scatter<update_window_dims = [1, 2, 3], "
                       "inserted_window_dims = [4, 6], "
                       "scatter_dims_to_operand_dims = [6, 7], "
                       "index_vector_dim = 8>")
  assert attr.update_window_dims == [1, 2, 3]
  assert attr.inserted_window_dims == [4, 6]
  assert attr.scattered_dims_to_operand_dims == [6, 7]
  assert attr.index_vector_dim == 8


@run
def test_gather_dimension_numbers():
  """Check that GatherDimensionNumbers attributes is available and usable."""

  attr = GatherDimensionNumbers.get(
      offset_dims=[1, 2],
      collapsed_slice_dims=[3, 4, 5],
      start_index_map=[6],
      index_vector_dim=7)
  assert attr is not None
  assert str(attr) == ("#mhlo.gather<offset_dims = [1, 2], "
                       "collapsed_slice_dims = [3, 4, 5], "
                       "start_index_map = [6], "
                       "index_vector_dim = 7>")
  assert attr.offset_dims == [1, 2]
  assert attr.collapsed_slice_dims == [3, 4, 5]
  assert attr.start_index_map == [6]
  assert attr.index_vector_dim == 7

结构化数据

元组和列表同属序列类型,且都可以按照特定顺序存放一组数据,数据类型不受限制,只要是 Python 支持的数据类型就可以,元组和列表最大的区别就是,列表中的元素可以进行任意修改,而元组中的元素无法修改,除非将元组整体替换掉,列表会将所有元素都放在一对中括号[ ]里面,相邻元素之间用逗号,分隔,而元组用()即可,他们的一些例子如下:

#!/usr/local/bin/python3
# Copyright 2022 shichaog
#list
num = [1, 2, 3, 4, 5, 6, 7]
program = [ "Python", "Java"]
#元组
num = (1, 2, 3, 4, 5, 6, 7)
program = ( "Python", "Java")

list 方法

增加

#!/usr/local/bin/python3
# Copyright 2022 shichaog
#list增加方法
num = [1, 2, 3, 4, 5, 6, 7]
program = [ "Python", "Java"]
print("----")
#list增加方法
list_add = num + program
print(list_add)
print("+++")
num.append('c')
print(num)
print("======")
num.append(program)
print(num)
print("||||")
num = [1, 2, 3, 4, 5, 6, 7]
program = ["Python", "Java"]
num.extend(program)
print(num)
print(".....")
num.insert(1, 'c++')
print(num)
输出为:
----
[1, 2, 3, 4, 5, 6, 7, 'Python', 'Java']
+++
[1, 2, 3, 4, 5, 6, 7, 'c']
======
[1, 2, 3, 4, 5, 6, 7, 'c', ['Python', 'Java']]
||||
[1, 2, 3, 4, 5, 6, 7, 'Python', 'Java']
.....
[1, 'c++', 2, 3, 4, 5, 6, 7, 'Python', 'Java']

list删除

#!/usr/local/bin/python3
# Copyright 2022 shichaog
num = [1, 2, 3, 4, 5, 6, 7, "Python", "Java",'c++']
print("----")
del num[0]
print(num)
del num[-1]
print(num)
print("+++")
del num[1:3]
print(num)
print("======")
num.pop(3)
print(num)
num.pop()
print(num)
print("||||")
num.remove(6)
print(num)
print(".....")
num.clear()
print(num)
输出为:
----
[2, 3, 4, 5, 6, 7, 'Python', 'Java', 'c++']
[2, 3, 4, 5, 6, 7, 'Python', 'Java']
+++
[2, 5, 6, 7, 'Python', 'Java']
======
[2, 5, 6, 'Python', 'Java']
[2, 5, 6, 'Python']
||||
[2, 5, 'Python']
.....
[]

修改

#!/usr/local/bin/python3
# Copyright 2022 shichaog
num = [1, 2, 3, 4, 5, 6, 7, "Python", "Java",'c++']
print("----")
num[1:3] = [1.0, "c"]
print(num)
num[0] = '0'
print(num)
print("+++")
num[1: 6: 2] = ['a', 'aa', 'aaa']
print(num)
print("====")
num[0] = ['0']
print(num)

输出
----
[1, 1.0, 'c', 4, 5, 6, 7, 'Python', 'Java', 'c++']
['0', 1.0, 'c', 4, 5, 6, 7, 'Python', 'Java', 'c++']
+++
['0', 'a', 'c', 'aa', 5, 'aaa', 7, 'Python', 'Java', 'c++']
====
[['0'], 'a', 'c', 'aa', 5, 'aaa', 7, 'Python', 'Java', 'c++']

字典

Python 字典(dict)是一种无序的、可变的序列,它的元素以“键值对(key-value)”的形式存储。相对地,列表(list)和元组(tuple)都是有序的序列,它们的元素在底层是挨着存放的。

#!/usr/local/bin/python3
# Copyright 2022 shichaog
a = {'one': 1, 'two': 2, 'three': 3}  #a是一个字典类型
print("----")
print(type(a))
print("+++")
dictname = {'key':'value1', 'key2':'value2','keyn':'valuen'} # 字典创建
print(dictname)
print("======")
print(dictname['key'])
print("....")
print(dictname.get('keyn+2', 'key not exist'))
print("|||||")
print(dictname['keyn+2']) #key不存在,直接调用会报错,通常使用上面的get方法
输出
----
<class 'dict'>
+++
{'key': 'value1', 'key2': 'value2', 'keyn': 'valuen'}
======
value1
....
key not exist
|||||
Traceback (most recent call last):
  File line 12, in <module>
    print(dictname['keyn+2'])
KeyError: 'keyn+2'

集合

Python 中的集合,和数学中的集合概念一样,用来保存不重复的元素,即集合中的元素都是唯一的,互不相同。从形式上看,和字典类似,Python 集合会将所有元素放在一对大括号 {} 中,相邻元素之间用“,”分隔,如下所示:{element1,element2,...,elementn},从内容上看,同一集合中,只能存储不可变的数据类型,包括整形、浮点型、字符串、元组,无法存储列表、字典、集合这些可变的数据类型。需要注意的是,数据必须保证是唯一的,因为集合对于每种数据元素,只会保留一份。

#!/usr/local/bin/python3
# Copyright 2022 shichaog
set={1,1,1,(1,1,1),'c','c'}
print(set)
print("====")
for ele in set:
    print(ele,end=' ')
输出
{1, (1, 1, 1), 'c'}
====
1 (1, 1, 1) c 

python提供了丰富的增删改查方法。

类是Python中所有数据的基础,Python中的一切都是对象,类是定义对象的方式。在Python中,类通过 class 关键字定义,类名通用习惯为首字母大写,Python3中类基本都会继承于object类,一个名为Dog的

#!/usr/local/bin/python3
# Copyright 2022 shichaog
class Dog:
    sound = 'Bark bark.' #这是属性
    movement = 'Walks like a dog.' #这也是属性

    def bark(self): #这是方法,参数self指代的是类对象自身
        print(self.sound)

    def move(self): #这也是方法,
        print(self.movement)

def main():
    Dog101 = Dog()
    Dog101.bark()
    Dog101.move()

if __name__ == '__main__': main()

上述代码函数的方法中,通常参数列表中第一个参数是self,其表示指向的是对象而不是类,当使用类名+()创建一个类实例对象时,self就指向了这个实例对象。

类属性

通常类的属性是可以更改的,比如Dog作为一个类,可以有贵宾犬、牧羊犬等很多种,如下例所示,通过Dog类创建了三种类型的Dog:

#!/usr/local/bin/python3
# Copyright 2022 shichaog
class Dog:
    def __init__(self, name, sound='Bark bark.', movemnt='move'):
        self._name = name
        self._sound = sound
        self._movement = movemnt
    def name(self):
        print(self._name)

    def bark(self):
        print(self._sound)

    def move(self):
        print(self._movement)

def main():
    Dog101 = Dog(name='type1')
    bulldog = Dog(name='type2', sound='wow')
    shepherd = Dog(name='type3', sound='ohh', movemnt='keep move')
    Dog101.name()
    bulldog.name()
    shepherd.name()

if __name__ == '__main__': main()

类有一个特殊的 init() 方法,当创建实例时,init() 方法被自动调用为创建的实例增加实例属性。init() 方法的第一个参数必须是 self(self代表类的实例,可以用别的名字,但建议使用约定成俗的self),后续参数则可以自由指定,和定义函数没有任何区别。通过init属性,在构造类对象时就可以根据对象的信息初始化相关属性变量值,参数和函数一样同样可以通过**kwargs传递参数。需要说明的是属性通常以下划线开始,通常并不直接修改属性值,而是通过class的方法修改属性值。

类继承

在一开始的创建类的时候提到了object基类,那里是继承的用法,这里以动物作为基类,Dog和elephant都是Animal的派生类。

#!/usr/local/bin/python3
# Copyright 2022 shichaog
class Animal:
    def __init__(self, **kwargs):
        if 'type' in kwargs: self._type = kwargs['type']
        if 'name' in kwargs: self._name = kwargs['name']
        if 'sound' in kwargs: self._sound = kwargs['sound']

    def type(self, t = None):
        if t: self._type = t
        try: return self._type
        except AttributeError: return None

    def name(self, n = None):
        if n: self._name = n
        try: return self._name
        except AttributeError: return None

    def sound(self, s = None):
        if s: self._sound = s
        try: return self._sound
        except AttributeError: return None

class Dog(Animal):
    def __init__(self, **kwargs):
        self._type = 'dog'
        if 'type' in kwargs: del kwargs['type']
        super().__init__(**kwargs) #这里的super()会调用父类的方法,即父类的初始化方法

class Panda(Animal):
    def __init__(self, **kwargs):
        self._type = 'elephant'
        if 'type' in kwargs: del kwargs['type']
        super().__init__(**kwargs)

def print_animal(o):
    if not isinstance(o, Animal):
        raise TypeError('print_animal(): requires an Animal')
    print(f'The {o.type()} is named "{o.name()}" and says "{o.sound()}".')

def main():
    a0 = Dog(name = 'Dog101', sound = 'bark')
    a1 = Panda(name = 'tuantuan', sound = 'hoot')
    print_animal(a0)
    print_animal(a1)

if __name__ == '__main__': main()

输出:
The dog is named "Dog101" and says "bark".
The elephant is named "tuantuan" and says "hoot".

异常处理

#!/usr/local/bin/python3
# Copyright 2022 shichaog
def main():
    x = int('string') 

if __name__ == '__main__': main()
执行后输出如下:
Traceback (most recent call last):
  File "/Users/exception.py", line 7, in <module>
    if __name__ == '__main__': main()
  File "/Users/exception.py", line 5, in main
    x = int('string')
ValueError: invalid literal for int() with base 10: 'string'

输出中的ValueError是python中的错误类型,表明这是一个值错误,Traceback是回调栈,其从上至下输出,可以看到main函数调用了第五行的x = int('string')。可以通过try except语句捕捉错误,如上面的错误类型可以用如下语句捕获:

#!/usr/local/bin/python3
# Copyright 2022 shichaog
def main():
    try:
        x = int('string')
    except ValueError:
        print('ValueError')
    except:
        print("unknow error")

if __name__ == '__main__': main()
输出:
Catch ValueError

这种语句的好处是,代码可以继续执行,如果没有捕获错误,程序将会终止执行。也可以不指定错误类型,另外除了python内置错误类型,也可以在编写代码时生成错误类型。其通过关键字raise实现。

#!/usr/local/bin/python3
# Copyright 2022 shichaog

def f1(*args):
    numargs = len(args)
    param1 = 0
    param2 = 0
    
    # initialize parameters
    if numargs < 1:
        raise TypeError(f'expected at least 1 argument, got {numargs}')
    elif numargs == 1:
        param1 = args[0]
    elif numargs == 2:
        (param1, param2) = args
    else: raise TypeError(f'expected at most 3 arguments, got {numargs}')

def main():
    f1() #这里参数个数等于0,因而会命中第一个异常raise语句
    print()

if __name__ == '__main__': main()
输出为:
Traceback (most recent call last):
  File "/Users/exceptions.py", line 22, in <module>
    if __name__ == '__main__': main()
  File "/Users/exceptions.py", line 19, in main
    f1() 
  File "/Users/exceptions.py", line 11, in f1
    raise TypeError(f'expected at least 1 argument, got {numargs}')
TypeError: expected at least 1 argument, got 0

文件IO

python提供了文件打开方法open,open返回的是一个文件对象,文件对象本身是一个迭代器,因而可以使用for循环读取文件,缺省情况下是以只读方式打开文件的,即open函数的第二个参数可以是’r’,也可以以写’w’,或者追加’a’方式打开文件,写将从文件头开始,而追加则不会覆盖文件已有的内容。如名为lines.txt文件内容如下:

01  first
02  second
03  third
04  fourth
05  fifth
06  sixth
07  seventh
08  eight
09  ninth
10  tenth

则用open方法以只读方式打开

#!/usr/local/bin/python3
# Copyright 2022 shichaog
def main():
    f = open('lines.txt', 'r')
    for line in f:
        print(line.rstrip())

if __name__ == '__main__': main()
输出为:
01  first
02  second
03  third
04  fourth
05  fifth
06  sixth
07  seventh
08  eight
09  ninth
10  tenth

open函数第二参数也可以不要,缺省就是只读的,但是加上是一个好习惯,通常也会加excpet语句,处理文件读写失败的情况。
文本文件的写方法如下代码所示,参数rt表示是只读方式打开txt文件。

#!/usr/local/bin/python3
# Copyright 2022 shichaog
def main():
    infile = open('lines.txt', 'rt')
    outfile = open('lines-copy.txt', 'wt')
    for line in infile:
        print(line.rstrip(), file=outfile)
        print('.', end='', flush=True)
    outfile.close()
    print('\ndone.')

if __name__ == '__main__': main()

内置函数

内置函数涉及数学、字符串、

#!/usr/local/bin/python3
# Copyright 2022 shichaog
x = '3'
y = int(x)

print(f'x is {type(x)}')
print(f'x is {x}')
print(f'y is {type(y)}')
print(f'y is {y}')

y =  3+4j

print(f'y is {type(y)}')
print(f'y is {y}')

y = complex(int(x), 4)

print(f'y is {type(y)}')
print(f'y is {y}')
输出为:
x is <class 'str'>
x is 3
y is <class 'int'>
y is 3
y is <class 'complex'>
y is (3+4j)
y is <class 'complex'>
y is (3+4j)

在这里插入图片描述

详细内置函数见python官方网址python3内置函数

模块

python标准库提供了很多现成的模块,比如sys,os,random,numpy,scipy,TensorFlow、pytorch等,使用pip/pip3安装这些模块,这些模块的使用通常是import或者from语句,下面是一个sys模块引用的简单例子,

#!/usr/local/bin/python3
# Copyright 2022 shichaog
import sys

def main():
    v = sys.version_info
    print('Python version {}.{}.{}'.format(*v))

if __name__ == '__main__': main()

python标准库提供的模块并不在这里详细一一列举,这里举个例子如何创建模块。

自定义模块

定义模块,只要使用文本编辑器,把一些python代码输入到文本中,然后以.py为后缀名进行保存,任何此类文件都会被认为是python模块。

比如说,下面的代码输入到一个文件中(这里使用my_module.py名,其它.py结尾的也是可以的,避免和系统自带模块重名),就可以看作是一个模块:

#!/usr/local/bin/python3
# Copyright 2022 shichaog

def hello():
    print("hello,world!")
def bye():
    print("bye-bye,world!")
if __name__ == '__main__':
	hello()

可以在新python文件中使用该模块,这里以test.py文件为例:

#!/usr/local/bin/python3
# Copyright 2022 shichaog
import my_module  #导入my_module.py的代码
my_module.hello() 
my_module.bye()

#也可以使用下面方法
from my_module import hello
hello()
bye()

除了模块名之外,python也可以导入指定目录路径。python代码的目录就称为包。因此,这类导入就称为包导入。事实上,包导入是把计算机上的目录变成python的一个命名空间。而属性就是目录中包含的子目录或者是模块文件。如有一个aa文件夹,里面有bb文件夹,bb里面有a.py这个文件。那么在aa和bb文件夹中分别放置一个__init__.py,之后,在命令行中import aa.bb.a,就可以导入模块a了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shichaog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值