深度学习之 Python3基础

Posted shichaog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度学习之 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(以上是关于深度学习之 Python3基础的主要内容,如果未能解决你的问题,请参考以下文章

深度学习之 Python3基础 上

麦子深度学习之-机器学习算法高级进阶

CP2003-Python做深度学习之Caffe设计实战

Python3学习之语言基础3

Tensorflow深度学习之十二:基础图像处理之二

python学习之基础:基础教程