5. 模块化编程

更新於 發佈於 閱讀時間約 33 分鐘

HI, 大家好。我是茶桁。

上一节中我们学习了Python基本的流程控制,并且预告了这一节的内容,就是将要学习「模块化编程」。那什么是模块化编程呢?按照维基百科的说法:

模块化编程(英语:modular programming),是强调将计算机程序的功能分离成独立的、可相互改变的“模块)”(module)的软件设计技术,它使得每个模块都包含着执行预期功能的一个唯一方面(aspect)所必需的所有东西。

说的简单一点,就是把程序进行封装(函数封装、面向对象、文件...)

OK,话不多说,让我们开始吧。

函数

什么是函数?

函数的英文单词为function, 我们将其翻译过来,就是“函数,功能”。

其实,函数就是一个具有特定功能的代码块。

函数的作用

函数的目的是封装,将特定功能的代码块进行封装,其目的是提高代码的重用性,从而提高开发效率,并且降低了后期的维护成本。

函数的定义和使用

函数的定义其实非常简单,我们用代码来写一下:

# 定义函数[基本结构]
def 函数名([参数列表]):
当前行数的具体功能的代码
当前行数的具体功能的代码
...

当然,函数在写完之后并不会自动执行,只是把函数定义了而已。如果想要使用定义完成的函数,需要用语法来进行函数的调用。

那么函数该如何调用呢?如下:

函数名()

示例:

# 函数的定义格式
def love():
print('i')
print('love')
print('u')

# 函数的调用
love()

当前程序运行输出结果:

i
love
u

以上代码可以得到函数的第一个特征:函数定义后,不调用不执行。还记得咱们上节课强调的流程控制吗?代码最基本流程顺序是自上而下的,所以,这个时候我们如果调用放在上方,例如:

# 函数的调用
love()

# 函数的定义格式
def love():
print('i')
print('love')
print('u')

此时因为love()调用的时候函数还未被定义,所以会执行报错:

NameError: name 'love' is not defined
raw-image

所以我们需要注意:不能在函数定义前调用函数。

另外,我们需要注意,函数的调用不受次数的影响,比如,我们定义好函数后,这个时候在后面调用三次:

love()
love()
love()

那执行后的结果应该是连着打印了三次结果。

和变量一样,函数的命名也是要遵守命名规范的:

  • 字母数字下划线,不能以数字开头
  • 严格区分大小写,且不能使用关键字
  • 命名最好有意义,且不要使用中文

现在我们想想,在love()函数被定义后,我们再来定义一个同名的函数会怎么样?

我们尝试一下,在刚才定义好的函数下方重复写一个同名的函数:

# 函数的定义格式
def love():
print('i')
print('love')
print('u')

def love():
print('u')
print("don't")
print('love')
print('me')

# 函数的调用
love()

直接结果:

u
don't
love
me

那,我们得到了实验结果:同样的函数名被再次定义之后,冲突的函数会被覆盖。

所以,最后我们总结一下函数的特征及注意事项:

1. 函数定义后,不调用不执行
2. 不能在函数定义前调用函数
3. 函数的调用不受次数影响
4. 函数的命名要遵守命名规范
- 字母数字下划线,不能以数字开头
- 严格区分大小写,不能使用关键字
- 命名最好有意义,且不要使用中文
5. 函数名不要冲突,冲突后会被覆盖

函数的参数

在定义函数的时候,我们需要注意给函数的参数。可以在参数列表的位置进行定义,这个称为形参。如果一个函数有形参,那么在调用的时候必须传递参数(实参)。实参将值传递给实参的过程,本质上就是变量赋值操作。

函数参数概念及分类

带有参数的函数,该如何定义?

在定义函数时,在小括号内可以定义形参(形式上的参数)

def love(w):
print(f'i love {w}')

# 调用带有形参的函数时,需要传递参数(实参)
love('马户')

执行结果为:

i love 马户

在这整个函数中,小括号内的w就是形参,在调用的时候的马户就是实参,在调用过程中将值传给了形参w

那么,如果我在调用的时候没有传递实参,就会直接报错:

love()

TypeError: love() missing 1 required positional argument: 'w'

形参可以是多个,这就是定义带有多个参数的函数:

def love(m, n):
print(f'{m} love {n}')

love('i', 'u')

执行结果:

1
i love u

如果形参是多个的话,那么有多少个形参就必须传递几个实参。并且参数都是按照顺序进行传递的。

如果少传一个参数,则同样会被错。

那,能不能多传呢?也不行,如果多传了参数,一样会报错。

至此,我们可以做如下总结:

  • 函数参数:调用时需要传递的数据
  • 函数参数的大类分为形参和实参
    • 形参意思:函数定义时的参数
    • 实参意思:函数调用时的参数
  • 形实关系:函数调用时,形参和实参个数需要一一对应

函数中的参数类型

在确定了什么是形参和实参之后,我们来看看,这两种参数都有哪些类型。

函数参数在类型上,包括:

  • 普通参数
  • 默认参数
  • 收集参数
  • 命名关键字参数
  • 关键字参数收集

普通参数

先来说说普通参数,其实就是位置参数,也叫顺序参数,也是必须传递的参数。

def love(m, n):
print(f'{m} love {n}')

love('i', 'u')

这段代码中,m, n就是普通参数,必须传递。

默认参数

有些函数在定义的时候,行参上就已经定义了默认值,那么这种就叫做默认参数。

在调用函数的时候,默认参数是可以不传值的。当传值之后,默认值就会被改变:

def func(x, y=20):
print(x, y)

func(2)

这段代码中的行参y就是默认参数,我们在调用函数func()只写了一个实参,也就是只传了一个值给函数。这个时候执行结果为:

2 20

我们修改一下,传两个值进去看看结果:

def func(x, y=20):
print(x, y)

func(2, 100)

执行结果:

2 100

可以看到,本来我们定义的行参y的默认值被改变了。

在定义默认参数的时候需要注意,函数中的默认参数只能全部定义在普通参数的后面,否则在调用函数的时候就会报错,比如以下这些情况:

# 第1种错误情况
def func(x=100, y=200, z):
print(x, y, z)

func(100,200,300)

# 第2种错误情况
def func(x=100, y, z=200):
print(x, y, z)

func(100, 200, 300)

# 第3种错误情况
def func(x, y=100, z):
print(x, y, z)

func(300,200,50)

收集参数

收集参数就是专门收集在函数调用时传递的多余的实参,或者我们可以理解为,不确定需要传递多少个实参,直接用一个行参来接收。

比如,我们现在有个需求就是需要计算用户输入的数字总和,我们按前面那个函数的定义方式为:

def func(x, y z=100):
print(x+y+z)

func(20,30)

这个函数中,我们输入2个值或者3个值都可以,但是当我们只输入一个值或者三个以上的时候,程序就会报错了。

那么有没有什么办法,不管用户输入多少个数字,我们都可以进行相加计算呢?

def func(x="+", *args):
if x == '+':
print('加法运算', args)
else:
print('减法运算', args)

func("-", 2, 3, 4, 5, 6, 7, 8)

这段代码执行结果为:

减法运算 (2, 3, 4, 5, 6, 7, 8)

虽然中间的运算代码我没有写,但是大家可以看到,已经可以接受不固定的多个参数了。

这个*args就是我们的收集参数。

在定义函数的时候,如果需要收集参数,那么这个形参前面需要加一个*号,例如*args。这里需要注意一点,*args并不是固定写法,你可以随意定义一个,只要前面有*号就可以了。比如下面这样:

def func(x="+", *y):
if x == '+':
print('加法运算', y)
else:
print('减法运算', y)

func("-", 2, 3, 4, 5, 6, 7, 8)

一样可以执行并得到一样的结果,这个时候,我们的*y就是收集参数。

收集参数也有两类,一种是普通的收集参数:专门用于收集多余的普通参数,形成一个新的元组。

语法: 参数前面加*, 例如:*args

还有一种是关键字收集参数:用于专门收集多余关键字实参,形成一个新的字典:

语法:参数前面加**, 例如:**kwargs

现在我们已经理解了普通的收集参数,那么在学习关键字收集参数之前,我们先来学习一下命名关键字参数

命名关键字参数

命名关键字是放在*号后面的参数,调用的时候强制必须传入制定参数名才能进行调用。

def func(a, b, c=3, *args, name):
print(a, b, c, "\n", *args, "\n", name)

func(1, 2, 3, 4, 5, 6, 7, 8, name='茶桁')

这段代码执行结果:

1 2 3 
4 5 6 7 8
茶桁

我们特意在中间加了换行字符来清晰的辨别*argsname

如果在这段代码中我稍微变一下,在执行函数的时候,实参里不标明name可以吗?

def func(a, b, c=3, *args, name):
print(a, b, c, "\n", *args, "\n", name)

func(1, 2, 3, 4, 5, 6, 7, 8, '茶桁')

执行之后我们收到了报错:

TypeError: func() missing 1 required keyword-only argument: 'name'

这段报错明显告诉我们,确实了一个必须的关键字参数name

那为什么会出现这种报错呢?这是因为在关键字参数之前,我们使用了*args来进行收集参数,那么无论你写多少,这些值都会被*args接收变成元组,那么后面的name自然就无法接受到值了。

让我们再来做一个实验,给命名关键字参数加上一个默认值,那么我们就能明显的看出问题:

def func(a, b, c=3, *args, name='_茶桁'):
print(a, b, c, "\n", *args, "\n", name)

func(1, 2, 3, 4, 5, 6, 7, 8, '茶桁')

这段代码执行结果:

1 2 3 
4 5 6 7 8 茶桁
_茶桁

可以看到,name给了默认值之后不再出现报错,而我们的实参也并未传到name里,而是全部被*args接收了。最后打印出了name的默认值_茶桁

利用命名参数的这种定义参数名称接收值的特点,我们就可以打乱之前普通参数传值的顺序性,比如:

def func(x, y):
print(x, "\t", y)

func(2, 3)
func(y = 2, x = 3)

执行结果为:

2 	 3
3 2

还是最开始的普通参数的写法,但是最后执行函数的时候,我们给实参指定了名称,这样传参顺序就没那么重要了。

所以,我们总结一下:

  • 关键字参数定义在收集参数后面
  • 关键字参数必须通过形参的名字来进行传递

关键字参数收集

前面我们在讲收集参数的结尾处提到了关键字参数收集,形式为**kwargs

def func(a, b, c=3, *args, name, age,  **kwargs):
print(a, b, c)
print(args) # 普通收集参数,会把多余的参数收集为元组
print(name, age)
print(kwargs) # 关键字参数收集,会把多余的关键字参数收集为字典

func(1, 2, 4, 112, 123, 321, 541, 231, name="茶桁", age=18, sex='male', height=185, x='x', y='y')

执行结果:

1 2 4
(112, 123, 321, 541, 231)
茶桁 18
{'sex': 'male', 'height': 185, 'x': 'x', 'y': 'y'}

从执行结果上我们可以看到,在nameage之后的所有参数都被传递到了**kwargs里,然后作为字典打印了出来。

在声明这个函数和执行函数的时候需要注意,这些参数都是有顺序的,如果在执行函数的时候再多传一个非关键字参数,这个时候程序就会报错,如果是关键字参数,则照样会被**kwargs接收。

在我们介绍完这些参数之后,我们最后再说明一下:

  • 形参声明的位置顺序:普通参数 -> 默认参数 -> 收集参数 -> 命名关键字参数 -> 关键字收集参数
  • def func(a, b, c=1, *args, d, **kw) 这段声明中,a,b为普通参数,c是默认参数,args是收集参数,d是命名关键字参数,kw是关键字收集参数
  • 极少情况下会同时出现上面五种形参,一般情况下为:普通参数,收集参数,关键字收集参数
  • 所有参数的摆放问题:
    • 实参:普通实参在前,关键字参数在后
    • 形参:关键字收集参数一定在最后出现,收集参数推荐在普通参数之后使用。
    • 推荐顺序:普通形参、收集参数、关键字收集参数

函数的返回值

一个函数除了可以完成一定功能之外,还可以用来安需要返回一些内容。在函数中,使用return关键字来制定返回数据,可以返回任意类型的数据。

函数的返回值会把数据返回到调用的地方,可以使用变量进行接收,或者作其他处理。

函数可以分为两类:

  1. 执行过程函数:函数体内完成一定的功能即可,没有返回值
  2. 具有返回值的函数:函数体内完成一定的功能,并且返回一个结果到函数调用处。

比如:

def func(a, b):
print(f'{a} love {b}')

以上函数就是一个没有返回值的函数,这个函数只是为了完成打印这句话的功能。

那么有返回值的函数是什么样子?

如果需要在函数中制定返回内容,我们需要使用return关键字。

# 有返回值的函数
def func(a, b):
res = f'{a} love {b}'
# 可以在函数体内,使用return返回内容
return res

r = func('老鼠', '布丁')
print(r)

执行结果为:

老鼠 love 布丁

在这段代码中,我们在func()的函数体内最后利用关键字return返回了任意内容,并且使用变量r接收了这个返回值,最后讲r打印了出来。

在调用func()这个函数的时候,函数中的返回值会返回到函数调用处。

我们再来研究一下return这个关键字,我们在return的前后都加上一段打印代码,看看会发生什么。

def func(a, b):
res = f'{a} love {b}'
print('这是return前')
return res
print('这是return后')

r = func('老鼠','布丁')
print(r)

执行结果:

这是return
老鼠 love 布丁

看到结果我们可以清楚,return之后的的代码并未继续执行,也就是说,我们如果要在函数体内执行其他任务,必须放在return之前执行,否则根本不会执行。那么我们可以得出结论:return必须放在一个定义函数的最后面。

Tips: 其实,即便没有return关键字或者returen之后没有任何内容,也有返回值,只是返回的是None值。

None是一个特殊的数据,表示什么都没有。查询类型可以看到返回 <class ‘NoneType’>

变量的作用域

作用域就是当前起作用,可用的范围区域。也就是变量的有效范围。

变量按作用域可以分为:

  • 局部变量: 在函数内部可以使用的变量
  • 全局变量:在函数内外都可以使用的变量

局部变量

让我们尝试下,如果函数内定义的变量在函数外使用会如何:

def func():
a = 20

print(a)

执行结果:

NameError: name 'a' is not defined

被告知a并未被定义。

可以看到,函数内定义的变量,在函数外连获取都做不到。这种在函数内定义的这个变量a,就是局部变量,它在函数外不能使用。

再让我们来看看将变量定义在函数外会是怎样的一种情况:

num = 10
def func():
print(num)

func()

执行结果:

10

func函数内,我们获取到了变量num的值并打印。那说明,在函数内我们可以获取函数外部的变量。

我们继续在继续看:

num = 10
def func():
num += 20
print(num)

func()

执行后报错:

UnboundLocalError: local variable 'num' referenced before assignment

这样我们可以看到,变量num在函数内虽然可以使用,但是无法进行更改。

那在函数外定义的所有变量都是如此吗?再让我们试试看:

items = [1, 2, 3, 4, 5]
def func():
items[0] = 20
print(items)

func()

执行结果:

[20, 2, 3, 4, 5]

由此我们看出,并不是所有的变量都不可在函数内进行更改。

其实,变量是分为两种的:

  • 可变数据类型:在函数外定义的变量,在函数内可以使用并改变
  • 不可变数据类型:在函数外定义的变量,在函数内只可以访问而无法改变

可变数据类型有列表和字典,其他的都是不可变数据类型。

全局变量

之前我们介绍的都是局部变量,那怎样定义全局变量呢?

在函数内使用global直接定义的变量,就是全局变量,函数内外都可以直接使用。

在函数外定义的变量,在函数内使用global关键字进行声明,那么也是全局变量。

例如:

num = 20
def func():
global num
num += 10
print(num)

func()

这个时候我们可以得到执行结果:

30

那有小伙伴就问了,如果我在函数外直接使用global定义全局变量可以吗?让我们来试试看就知道了:

global num
num = 20
def func():
num += 10
print(num)

func()

执行之后得到报错:

UnboundLocalError: local variable 'num' referenced before assignment

这样我们就得到了结果:不可以。

在整个程序中,我们可以使用两个函数方法来获取数据:

globals()用来获取全局数据,locals()用来获取当前作用域的数据

讲到这里,我们再来多看一组代码:

# 函数的作用域
def outer():
print('this is outer func...')
def inner():
print('this is inner func...')

outer()
inner()

这段代码执行结果为:

this is outer func...

NameError: name 'inner' is not defined

正常执行了outer()内的打印,然后又报了一个错误,提示inner函数未定义。

说明,不只是变量有作用域,函数一样也有作用域。要想inner函数内的打印也起作用,我们需要在函数内就调用执行inner()

# 函数的作用域
def outer():
print('this is outer func...')
def inner():
print('this is inner func...')
inner() # 在函数内执行
outer()

这样,我们执行的结果就是:

this is outer func...
this is inner func...

如果我们在外层函数中定义一个局部变量,能在内层函数中使用吗?

# 函数的作用域
def outer():
a = 2
print('this is outer func...')
def inner():
a += 1
print('this is inner func...')
print(a)
inner()
outer()

执行之后得到报错:

UnboundLocalError: local variable 'a' referenced before assignment

说明并不可以。

nonlocal关键字

那么,到底有没有什么办法在内函数中使用上一层函数中的局部变量呢?答案是有办法。

在内函数中如果想要使用外层函数的变量,那么需要使用nonlocal关键字,可以引用上一层函数中定义的局部变量。

# 定义一个外层函数
def outer():
# 外函数的局部变量
num = 10
# 内函数, 局部函数, 在函数的内部定义的函数
def inner():
# nonlocal 关键字在局部函数中使用
nonlocal num # 可以引用上一层函数中定义的局部变量
num += 1
print(num)
inner()
outer()

执行后返回结果:

11

至此,我们通过使用nonlocal关键字,成功拿到了外层函数定义的变量num并使用。最后打印出使用的结果。

这里我们要注意,nonlocal虽然可以引用上一层函数中定义的局部变量,但是这并不代表提升为了全局变量。

既然我们有了global关键字可以提升变量为全局变量,为什么还需要一个nonlocal关键字呢?是不是有点多此一举?

这两者的功能上并不相同。global关键字修饰变量后标识该变量是全局变量,对该变量进行修改就是修改全局变量,而nonlocal关键字修饰变量后标识该变量是上一级函数中的局部变量,如果上一级函数中不存在该局部变量,nonlocal位置会发生错误(最上层的函数使用nonlocal修饰变量必定会报错)。

关于函数的文档

我们在一个未定义任何变量和函数的空白文档中打印一下全局数据:

print(globals())

执行结果:

{
'__name__': '__main__',
'__doc__': 'Automatically created module for IPython interactive environment',
'__package__': None,
'__loader__': None,
'__spec__': None,
'__builtin__': <module 'builtins' (built-in)>,
'__builtins__': <module 'builtins' (built-in)>,
'_ih': ['',
'print(globals())'],
'_oh': {},
'_dh': [PosixPath('/Users/xx/git/AI_Cheats/Python'),
PosixPath('/Users/xx/git/AI_Cheats/Python')],
'In': ['',
'print(globals())'],
'Out': {},
'get_ipython': <bound method InteractiveShell.get_ipython of <ipykernel.zmqshell.ZMQInteractiveShell object at 0x105be29e0>>,
'exit': <IPython.core.autocall.ZMQExitAutocall object at 0x105be3280>,
'quit': <IPython.core.autocall.ZMQExitAutocall object at 0x105be3280>,
'open': <function open at 0x10488e710>,
'_': '',
'__': '',
'___': '',
'__vsc_ipynb_file__': '/Users/xx/git/AI_Cheats/Python/globals.ipynb',
'_i': '',
'_ii': '',
'_iii': '',
'_i1': 'print(globals())'
}

我们来看这个打印出来的json

类似于__name__这种前后有__ __的数据,称之为“魔术变量”。我们并未定义,但是已经存在了。

如果脚本作为主程序,那么__name__值是__main__,如果是当作一个模块在另外一个脚本中引用去使用,那么值就是当前文件的命名。

__doc__当前脚本的文档说明,在当前脚本当中的第一个三引号注释就是当前脚本的说明文档。比如,我们在这个空白的文档中写一段三引号注释

"""
这里是整个文档的说明部分。
"""
def func():
pass

然后我们直接将doc打印出来查看:

print(__doc__)

可以看到输出内容:

这里是整个文档的说明部分。

这种文档其实不止适用于python文件,对于定义的函数依然适用。比如,我们执行定义了一个函数,并在函数内部用三引号进行注释:

def func():
"""
这里是让你写一写函数的文档说明的。
需要说明当前函数的作用,
如果当前函数还有形参,那么也需要对形参进行一一说明。
name: 这个是一个name参数,用于接收姓名
age: 这个参数是表示年龄
:return: 此处说明当前函数的返回值
"""
pass

这个时候,我们在下方执行:

print(func.__doc__)

可以看到我们在注释内定义的说明文档被打印出来了:

raw-image

这样,我们不仅可以在自己写函数的时候在上方清晰的写明当前函数的作用及参数,我们还可以使用此方法,查找其他人所写的函数的一些说明。

在我们平时写代码的时候,养成一个好习惯是非常有必要的。

总结一下:

  • print(__name__): 获取当前脚本的文件名
  • print(__doc__): 获取当前脚本的说明文档
  • print(func.__doc__): 获取当前函数的说明文档

练习:函数封装

我们上一讲中的练习中,我们打印了乘法表,矩形图形,还计算了12生肖。这里我们就将乘法表来封装成函数,实现我们上节课留的其中一道思考题:反向打印。

我们先将打印乘法表封装起来:

# 定义函数,打印九九乘法表
def multiply_table():
"""
当前函数的功能是打印出乘法表
"""
for x in range(1, 10):
for y in range(1, x+1):
print(f'{x}X{y}={x*y}', end=" ")
print()

这样,我们在其他地方执行multiply_table()函数的时候,就可以直接打印出乘法表。

现在让我们给这个函数多加一些功能:

# 定义函数,打印九九乘法表
def multiply_table(i=0):
"""
当前函数的功能是打印出乘法表
i=0; i 这个参数可以用来控制正向输出和方向输出,0的时候正向,1的时候反向,默认为0
"""
if i:
rs = range(9, 0, -1)
else:
rs = range(1, 10)

for x in rs:
for y in range(1, x+1):
print(f'{x}X{y}={x*y}', end=" ")
print()

我们执行函数的时候,输入1来试试看:

multiply_table(1)

输出结果:

9X1=9 9X2=18 9X3=27 9X4=36 9X5=45 9X6=54 9X7=63 9X8=72 9X9=81 
8X1=8 8X2=16 8X3=24 8X4=32 8X5=40 8X6=48 8X7=56 8X8=64
7X1=7 7X2=14 7X3=21 7X4=28 7X5=35 7X6=42 7X7=49
6X1=6 6X2=12 6X3=18 6X4=24 6X5=30 6X6=36
5X1=5 5X2=10 5X3=15 5X4=20 5X5=25
4X1=4 4X2=8 4X3=12 4X4=16
3X1=3 3X2=6 3X3=9
2X1=2 2X2=4
1X1=1

可以看到,我们的控制结果被成功打印出来。至此,这个有一些小功能的九九乘法表就封装完成了。

那么这一节课就不留思考题了,大家课后熟练掌握一下封装函数和变量的作用域,我们下节课来学习一些高阶函数, 好,下课。

avatar-img
9會員
62內容數
从基础开始,再到Python,然后是CV、BI、NLP等相关技术。从头到尾详细的教授一边人工智能。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
茶桁的沙龍 的其他內容
Hi,大家好。我是茶桁。 在前面几节课的基础之上,我们今天开始尝试在Python中控制流程。这中间,让我们来做一些实际的练习。 Python语句的分类 让我们先了解一下Python语句的分类。 在Python中,可分为单行代码和代码块/组, 顾名思义,单行代码就是一行的Python代码,而代
Python的系列课程是写给零基础的小白看的,如果基础比较好的小伙伴可以暂时先不关注,等待后续课程。 Hi, 大家好,我是茶桁。 之前的课程已经给大家讲解了Python相关特性和基本语法。那么这节课呢,我们尝试着从最简单的脚本来开始认识Python。 在开始这节课之前呢,我是默认大家已经安装好
千里之行始于足下。 大家好,我是茶桁,这里是我们《AI秘籍》的第一节,让我们先从Python来开始好好的打好基础。 第一堂课,我们先从最基础的Python特性开始,当然,还有一些基本语法。 上来就开始讲特性和语法,说明我们将会遗弃惯用的“环境搭建”等更基础的内容,那些内容网上已经很丰富了,一查
Hi,大家好。我是茶桁。 前两节我们学习了基本的Python特性和语法,并且认识了一些基本的Python脚本。今天,我们来学习一下Python的运算符,而我们选择的版本为Python3。 什么是运算符 为了能让我们的学习顺利进行下去,首先我们需要先弄明白:什么是运算符。 这里举一个简单的栗子
Hi,大家好。我时茶桁。 最近,我花了几天时间仔细思考了一下即将要开始写的专栏《AI秘籍》,再根据自己的能力大概规划了一下。目前大致已经理出了一些相关信息可以分享给大家。 专栏形式 本次专栏应该会以文章的形式先和大家见面,后续还会根据能力以原本的文章为准录制视频版本。 专栏平台 就如前一篇
Hi, 大家好,我是茶桁,这里为自己做个广告,目前打算开始写一整个系列《AI秘籍》。 这一段时间内我写过一个系列《零基础学习大语言模型》(目前还没写完)。 说实话,这个系列其实原出处并不是我,严谨的说来,有涉嫌擦边“洗稿”的嫌疑,所以最后放弃了收费的想法,仅仅对一些模型,资源以及计算结果进行了补
Hi,大家好。我是茶桁。 在前面几节课的基础之上,我们今天开始尝试在Python中控制流程。这中间,让我们来做一些实际的练习。 Python语句的分类 让我们先了解一下Python语句的分类。 在Python中,可分为单行代码和代码块/组, 顾名思义,单行代码就是一行的Python代码,而代
Python的系列课程是写给零基础的小白看的,如果基础比较好的小伙伴可以暂时先不关注,等待后续课程。 Hi, 大家好,我是茶桁。 之前的课程已经给大家讲解了Python相关特性和基本语法。那么这节课呢,我们尝试着从最简单的脚本来开始认识Python。 在开始这节课之前呢,我是默认大家已经安装好
千里之行始于足下。 大家好,我是茶桁,这里是我们《AI秘籍》的第一节,让我们先从Python来开始好好的打好基础。 第一堂课,我们先从最基础的Python特性开始,当然,还有一些基本语法。 上来就开始讲特性和语法,说明我们将会遗弃惯用的“环境搭建”等更基础的内容,那些内容网上已经很丰富了,一查
Hi,大家好。我是茶桁。 前两节我们学习了基本的Python特性和语法,并且认识了一些基本的Python脚本。今天,我们来学习一下Python的运算符,而我们选择的版本为Python3。 什么是运算符 为了能让我们的学习顺利进行下去,首先我们需要先弄明白:什么是运算符。 这里举一个简单的栗子
Hi,大家好。我时茶桁。 最近,我花了几天时间仔细思考了一下即将要开始写的专栏《AI秘籍》,再根据自己的能力大概规划了一下。目前大致已经理出了一些相关信息可以分享给大家。 专栏形式 本次专栏应该会以文章的形式先和大家见面,后续还会根据能力以原本的文章为准录制视频版本。 专栏平台 就如前一篇
Hi, 大家好,我是茶桁,这里为自己做个广告,目前打算开始写一整个系列《AI秘籍》。 这一段时间内我写过一个系列《零基础学习大语言模型》(目前还没写完)。 说实话,这个系列其实原出处并不是我,严谨的说来,有涉嫌擦边“洗稿”的嫌疑,所以最后放弃了收费的想法,仅仅对一些模型,资源以及计算结果进行了补
你可能也想看
Google News 追蹤
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
這篇內容,將會講解什麼是腳本函式,以及與腳本函式相關的知識。包括腳本的簡介、使用函式(或全域變數)的注意事項、定義全域變數、定義函式、什麼是宣告、局部變數的應用。
Thumbnail
Python的模組和庫是可重用的程式碼塊,可透過import語句引入。特定部分可以透過from和import引入,並可使用as指定別名。第三方模組可透過pip工具安裝並在程式碼中使用。此外,也可以創建自定義模組並在其他Python文件中引用。
Thumbnail
在Python中,我們可以用def關鍵字定義函數,並透過函數名稱呼叫它。函數參數可以是必填、關鍵字、默認或不定長度的類型。return語句負責結束函數並回傳值。全域變數可以在整個程序中使用,而區域變數只能在特定函數內使用。我們還可以在一個文件中定義函數,然後在另一個文件中呼叫它。
Thumbnail
Python語法包括條件語句、迴圈、函數和變數的使用。條件語句如if、elif和else用於進行條件判斷,for和while是兩種主要的迴圈,def用於定義函數。變數可以被賦予數字或字符串,並可使用類型提示來指定變數的類型。註解可以是單行或多行,並可用於解釋函數或類的用途和作用。
Thumbnail
今天來介紹python的函式 函式在python中是非常重要的一環,因為到了後期,程式會越來越複雜。 而函式可以想成是容易管理的小程式,當我們需要使用時,只需呼叫即可。
對於程序式編程來說,程式是由一系列的指令組成,例如計算數值、印出訊息、修改變數、呼叫子程序、配置變數的記憶體空間等。定義函式是為了讓一些程序可以重複利用,因此稱為子程序,其中參數為子程序中特別的變數,讓我們能夠透過它們控制子程序的行為。函式的回傳值只是一種方便將結果帶回來的方法,但一般只能回傳一個值
Thumbnail
宣告變數 變數是程式中用來儲存和表示數據的標識符號​,並將變數存放在某個記憶體位子 可以用ID的方法查找變數存在哪個記憶體,此方法有利於以後查找問題用。 在大多數程式語言中,變數需要事先聲明(宣告)並賦值。 而Python是一種動態類型語言,不需要顯式宣告變數類型,而是在賦值時自動進行推斷。
Thumbnail
本文讓我們來淺談一下類別是什麼? 若想看詳細一點的python官方教學可點此連結 Python 的類別(Class)是一種面向物件導向程式設計的概念,讓你能夠創建具有屬性和方法的物件。類別是對現實世界中事物的抽象,它包含數據和操作這些數據的方法。它非常的抽象,想像一個類別就像是一個蛋糕模具,
Thumbnail
本文將介紹自定函式及應用,利用程式範例解釋為什麼要用到自定函式 自定函式好處當然就是,讓你的程式碼看起來比較簡潔,在重複使用到的程式碼區塊,可以包裝成函式,讓你重複使用它。
Thumbnail
本文將介紹 Python 中的閉包(Closure),我們將從閉包的定義開始介紹,然後是閉包的用途,以及最後的實作範例。
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
這篇內容,將會講解什麼是腳本函式,以及與腳本函式相關的知識。包括腳本的簡介、使用函式(或全域變數)的注意事項、定義全域變數、定義函式、什麼是宣告、局部變數的應用。
Thumbnail
Python的模組和庫是可重用的程式碼塊,可透過import語句引入。特定部分可以透過from和import引入,並可使用as指定別名。第三方模組可透過pip工具安裝並在程式碼中使用。此外,也可以創建自定義模組並在其他Python文件中引用。
Thumbnail
在Python中,我們可以用def關鍵字定義函數,並透過函數名稱呼叫它。函數參數可以是必填、關鍵字、默認或不定長度的類型。return語句負責結束函數並回傳值。全域變數可以在整個程序中使用,而區域變數只能在特定函數內使用。我們還可以在一個文件中定義函數,然後在另一個文件中呼叫它。
Thumbnail
Python語法包括條件語句、迴圈、函數和變數的使用。條件語句如if、elif和else用於進行條件判斷,for和while是兩種主要的迴圈,def用於定義函數。變數可以被賦予數字或字符串,並可使用類型提示來指定變數的類型。註解可以是單行或多行,並可用於解釋函數或類的用途和作用。
Thumbnail
今天來介紹python的函式 函式在python中是非常重要的一環,因為到了後期,程式會越來越複雜。 而函式可以想成是容易管理的小程式,當我們需要使用時,只需呼叫即可。
對於程序式編程來說,程式是由一系列的指令組成,例如計算數值、印出訊息、修改變數、呼叫子程序、配置變數的記憶體空間等。定義函式是為了讓一些程序可以重複利用,因此稱為子程序,其中參數為子程序中特別的變數,讓我們能夠透過它們控制子程序的行為。函式的回傳值只是一種方便將結果帶回來的方法,但一般只能回傳一個值
Thumbnail
宣告變數 變數是程式中用來儲存和表示數據的標識符號​,並將變數存放在某個記憶體位子 可以用ID的方法查找變數存在哪個記憶體,此方法有利於以後查找問題用。 在大多數程式語言中,變數需要事先聲明(宣告)並賦值。 而Python是一種動態類型語言,不需要顯式宣告變數類型,而是在賦值時自動進行推斷。
Thumbnail
本文讓我們來淺談一下類別是什麼? 若想看詳細一點的python官方教學可點此連結 Python 的類別(Class)是一種面向物件導向程式設計的概念,讓你能夠創建具有屬性和方法的物件。類別是對現實世界中事物的抽象,它包含數據和操作這些數據的方法。它非常的抽象,想像一個類別就像是一個蛋糕模具,
Thumbnail
本文將介紹自定函式及應用,利用程式範例解釋為什麼要用到自定函式 自定函式好處當然就是,讓你的程式碼看起來比較簡潔,在重複使用到的程式碼區塊,可以包裝成函式,讓你重複使用它。
Thumbnail
本文將介紹 Python 中的閉包(Closure),我們將從閉包的定義開始介紹,然後是閉包的用途,以及最後的實作範例。