百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

Python必学基础知识之函数 python 函数中的函数

liebian365 2024-11-03 15:46 23 浏览 0 评论

本章主要内容

  • 定义函数
  • 使用函数参数
  • 用可变对象作为参数
  • 理解局部变量和全局变量
  • 创建和使用生成器函数
  • 创建和使用lambda表达式
  • 使用装饰器

本章假定读者至少熟悉另一种计算机语言的函数定义方法,包括函数定义、实参(argument)和形参(parameter)等概念。

9.1 基本的函数定义

Python函数定义的基本语法如下:

def name(parameter1, parameter2, . . .):
    body

与代码流程控制结构一样,Python用缩进来界定函数体。以下示例将之前计算阶乘的代码放入函数体中,这样只需调用fact函数即可得到阶乘值了:

>>> def fact(n):
...     """ Return the factorial of the given number. """    ?---  ?
...     r = 1
...     while n > 0:
...         r = r * n
...         n = n - 1
...     return r           ?---  ?
...

第二行?是可选的文档字符串(docstring),可通过fact.__doc__读取其值。文档字符串用于描述函数对外表现出来的功能及所需的参数,而注释(comment)则是记录代码工作原理的内部信息。文档字符串紧随在函数定义的第一行后面,通常用3重引号包围起来,以便能跨越多行。代码助手只会提取文档字符串的第一行。标准的多行文档字符串写法,是在第一行中给出函数的概述,第二行是空行,然后是其余的详细信息。return语句之后的值将会返回给函数的调用者?。

过程与函数


在某些编程语言中,无返回值的函数被称为“过程”。虽然Python允许编写不含return语句的函数,但这些函数还不是真正的过程。所有的Python过程都是函数。如果过程体没有显式地执行return语句,则会返回特殊值None。如果执行了return arg语句,则值arg会被立即返回。return语句执行之后,函数体中的其余语句都不会执行。因为Python没有真正的过程,所以均被称为“函数”。

虽然Python函数都带有返回值,但是否使用这个返回值则由写代码的人决定:

>>> fact(4)     ?---  ?
24     ?---  ?
>>> x = fact(4)     ?---  ?
>>> x
24
>>>

一开始返回值没有与任何变量关联?,fact函数的值只是被解释器打印出来而已?。然后返回值与变量x关联?。

9.2 多种函数参数

大多数函数都需要形参,每种编程语言都有各自的函数形参定义规则。Python非常灵活,提供了3种函数形参的定义方式。本节将介绍这些定义方式。

9.2.1 按位置给出形参

在Python中,最简单的函数传形参方式就是按位置给出。在函数定义的第一行中,可以为每个形参指定变量名称。当调用函数时,调用代码中给出的形参将按顺序与函数的形参变量逐一匹配。以下函数计算x的y次幂:

>>> def power(x, y):
...     r = 1
...     while y > 0:
...         r = r * x
...         y = y - 1
...     return r

>>> power(3, 3)
27

上述用法要求,调用代码使用的形参数量与函数定义时的形参数量应完全匹配,否则会引发TypeError:

>>> power(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: power() missing 1 required positional argument: 'y'
>>>

默认值


函数的形参可以有默认值,可以在函数定义的第一行中给出该默认值,如下所示:

def fun(arg1, arg2=default2, arg3=default3, ...)

可以为任何数量的形参给出默认值。带默认值的形参必须位于形参列表的末尾,因为与大多数编程语言一样,Python也是根据位置来把实参与形参匹配起来的。给函数的实参数量必须足够多,以便让形参列表中最后一个不带默认值的形参能获取到实参。更为灵活的机制参见9.2.2节。

以下函数同样也会计算x的y次幂。但如果在函数调用时没有给出y,则会用默认值2,于是就成了计算平方的函数:

>>> def power(x, y=2):
...     r = 1
...     while y > 0:
...         r = r * x
...         y = y - 1
...     return r

以下交互式会话演示了默认实参的效果:

>>> power(3, 3)
27
>>> power(3)
9

9.2.2 按形参名称传递实参

也可以使用对应的函数形参的名称将实参传给函数,而不是按照形参的位置给出。继续上面的交互示例,可以键入

>>> power(2, 3) 
8
>>> power(3, 2)
9
>>> power(y=2, x=3)
9

最后提交给power函数的实参带了名称,因此与顺序无关。实参与power函数定义中的同名形参关联起来,得到的是3^2的结果。这种实参传递方式被称为关键字传递(keyword passing)。

如果函数需要带有大量实参,并且大多数实参都有默认值,那么联合使用关键字传递和默认实参功能可能就非常有用了。例如,有个生成当前目录下文件信息清单的函数,可用布尔型实参指定清单中是否要包含每个文件的大小、最后修改日期等信息。函数定义如下所示:

def list_file_info(size=False, create_date=False, mod_date=False, ... ):
    ...获取文件名...  
    if size:
        # 获取文件大小
    if create_date:
        # 获取文件的创建日期
    # 其他功能
    return fileinfostructure

然后用关键字传递方式调用,指明需要包含的文件信息(在本例中为文件大小和修改日期,但不是创建日期):

fileinfo = list_file_info( size = True,mod_date = True)

这种参数处理方式特别适用于非常复杂的函数,图形用户界面(GUI)中常会用到。如果用过Tkinter包建立Python的GUI程序,就会发现这种可选的关键字命名实参是非常有用的。

9.2.3 变长实参

Python函数也可以定义为实参数量可变的形式,定义方式有两种。一种用于处理实参预期相对明了的情况,实参列表尾部数量不定的实参将会被放入一个列表中。另一种方式可将任意数量的关键字传递实参放入一个字典中,这些实参均是在函数形参列表中不存在同名形参的。下面将介绍这两种机制。

1.位置实参数量不定时的处理

当函数的最后一个形参名称带有“*”前缀时,在一个函数调用中所有多出来的非关键字传递实参(即这些按位置给出的实参未能赋给合适的形参)将会合并为一个元组赋给该形参。下面用这种简单方式来实现一个求数字列表中最大值的函数。

首先,实现函数:

>>> def maximum(*numbers):
...     if len(numbers) == 0:
...         return None
...     else:
...         maxnum = numbers[0]
...         for n in numbers[1:]:
...             if n > maxnum:
...                 maxnum = n
...         return maxnum
...

接下来,测试该函数的功能:

>>> maximum(3, 2, 8)
8
>>> maximum(1, 5, 9, -2, 2)
9

2.关键字传递实参数量不定时的处理

按关键字传递的实参数量不定时,也能进行处理。如果形参列表的最后一个形参前缀为“**”,那么所有多余的关键字传递实参将会被收入一个字典对象中。字典的键为多余实参的关键字(形参名称),字典的值为实参本身。这里的“多余”是指,传递实参的关键字匹配不到函数定义中的形参名称。

例如:

>>> def example_fun(x, y, **other):
...     print("x: {0}, y: {1}, keys in 'other': {2}".format(x, 
...           y, list(other.keys())))
...     other_total = 0
...     for k in other.keys():
...         other_total = other_total + other[k]
...     print("The total of values in 'other' is {0}".format(other_total))

在交互会话中测试一下,以上函数可以处理用关键字foo和bar传入的实参,即便foo和bar不属于函数定义中给出的形参名也没问题:

>>> example_fun(2, y="1", foo=3, bar=4)
x: 2, y: 1, keys in 'other': ['foo', 'bar']
The total of values in 'other' is 7

9.2.4 多种参数传递方式的混用

Python函数的所有实参传递方式可以同时使用,但一不小心就可能会引起混乱。混合使用多种实参传递方式的一般规则是,先按位置传递实参,接着是命名实参,然后是带单个“*”的数量不定的位置传递实参,最后是带“**”的数量不定的关键字传递实参。详细信息参见官方文档。

速测题:函数和参数 该如何编写函数,接收任意数量的未命名实参,并逆序打印出来?

如何创建过程,也就是无返回值的函数?

如果用变量捕获函数的返回值,会发生什么?

9.3 将可变对象用作函数实参

函数的实参传递的是对象的引用,形参则成为指向对象的新引用。对于不可变对象(如元组、字符串和数值),对形参的操作不会影响函数外部的代码。但如果传入的是可变对象(如列表、字典或类的实例),则对该对象做出的任何改动都会改变该实参在函数外引用的值。函数内部对形参的重新赋值不会影响实参,如图9-1和图9-2所示:

>>> def f(n, list1, list2):
...     list1.append(3)
...     list2 = [4, 5, 6]
...     n = n + 1
...
>>> x = 5
>>> y = [1, 2]
>>> z = [4, 5]
>>> f(x, y, z)
>>> x, y, z
(5, [1, 2, 3], [4, 5])

图9-1 在函数f()开始执行时,各初始变量和函数形参分别都指向同一个对象

图9-2 在函数f()执行完毕后,y(函数内的list1)引用的值已经发生了变化,而n和list2则指向了不同的对象

图9-1和图9-2演示了调用函数f时发生的事情。变量x没有变化,因为x是不可变的。而函数形参n则被指向了新的值6。同理,变量z没有变化,因为在函数f内,对应的形参list2被指向了新的对象[4,5,6]。只有y发生了变化,因为其指向的实际列表发生了变化。

速测题:函数参数为可变类型 如果将列表或字典作为参数值传入函数,那么(在函数内)对其进行修改会导致什么结果?哪些操作可能会导致改动对函数外部也是可见的?可采取什么措施降低这种改动风险?

9.4 局部变量、非局部变量和全局变量

下面回顾一下本章开始介绍过的fact函数的定义:

>>> def fact(n):
        """ 返回给定值的阶乘 """
        r = 1
        while n > 0:
            r = r * n
            n = n - 1
        return r

变量r和n对于fact函数的任何调用都是局部(local)的,在函数执行期间,它们的变化对函数外部的任何变量都没有影响。函数形参列表中的所有变量,以及通过赋值(如fact函数中的r = 1)在函数内部创建的所有变量,都是该函数的局部变量。

在使用变量之前,用global语句对其进行声明,可以显式地使其成为全局(global)变量。函数可以访问和修改全局变量。全局变量存在于函数之外,所有将其声明为全局变量的其他函数,以及函数之外的代码,也可以对其进行访问和修改。以下示例演示了局部变量和全局变量的差异:

>>> def fun():
...     global a
...     a = 1
...     b = 2
...

以上示例中定义的函数,将a视为全局变量,而视b为局部变量,并对a和b进行了修改。

下面测试一下上述函数:

>>> a = "one"
>>> b = "two"

>>> fun()
>>> a
1
>>> b
'two'

在fun函数内对a的赋值,同时也是对fun函数外部现存的全局变量a进行操作。因为a在fun函数中被指定为global,所以赋值会将该全局变量从"one"修改为1。对b来说则不一样,fun函数内部名为b的局部变量一开始指向fun函数外部的变量b的相同值[1],但赋值操作让b指向了函数fun内的新值。

nonlocal语句与global语句类似,它会让标识符引用最近的闭合作用域(enclosing scope)中已绑定的变量。第10章中将会更详细地介绍作用域和命名空间,现在的重点是要理解,global语句是对顶级变量使用的,而nonlocal语句则可引用闭合作用域中的全部变量,如代码清单9-1所示。

代码清单9-1 nonlocal.py文件

g_var = 0          ?---  inner_test函数中的g_var绑定为同名的顶级变量
nl_var = 0
print("top level-> g_var: {0} nl_var: {1}".format(g_var, nl_var))
def test(): 
    nl_var = 2     ?---  inner_test函数中的nl_ var绑定为test函数中的同名变量
    print("in test-> g_var: {0} nl_var: {1}".format(g_var, nl_var))
    def inner_test():
        global g_var   ?---  inner_test函数中的g_var绑定为同名的顶级变量
        nonlocal nl_var   ?---  inner_test函数中的nl_var绑定为test函数中的同名变量
        g_var = 1
        nl_var = 4
        print("in inner_test-> g_var: {0} nl_var: {1}".format(g_var,
            nl_var))

    inner_test()
    print("in test-> g_var: {0} nl_var: {1}".format(g_var, nl_var))

test()
print("top level-> g_var: {0} nl_var: {1}".format(g_var, nl_var))

上述代码运行后会打印出以下结果:

top level-> g_var: 0 nl_var: 0
in test-> g_var: 0 nl_var: 2
in inner_test-> g_var: 1 nl_var: 4
in test-> g_var: 1 nl_var: 4
top level-> g_var: 1 nl_var: 0

注意,顶级变量nl_var的值没有受到影响。如果inner_test函数中包含global nl_var语句,那么nl_var的值就会受影响了。

最起码的一点就是,如果想对函数之外的变量赋值,就必须将其显式声明为nonlocal或global。但如果只是要访问函数外的变量,则不需要将其声明为nonlocal或global。如果Python在函数本地作用域中找不到某变量名,就会尝试在全局作用域中查找。因此,对全局变量的访问会自动发送给相应的全局变量。个人不建议使用这种便捷方式。如果所有全局变量都被显式地声明为global,阅读代码的人就会看得更清楚。以后,则还可能有机会将全局变量的使用限制在函数内部,仅限极少数情况下才会用到。

动手题:全局变量和局部变量 假定x = 5,在运行以下的funct_1()之后,x的值会是什么?运行funct_2()之后呢?

def funct_1(): x = 3 def funct_2(): global x x = 2

9.5 将函数赋给变量

与其他Python对象一样,函数也可以被赋值,如下所示:

>>> def f_to_kelvin(degrees_f):     ?---  定义f_to_kelvin函数
...     return 273.15 + (degrees_f - 32) * 5 / 9
...
>>> def c_to_kelvin(degrees_c):     ?---  定义c_to_kelvin函数
...     return 273.15 + degrees_c
...
>>> abs_temperature = f_to_kelvin     ?---  将f_to_kelvin函数赋给变量
>>> abs_temperature(32)
273.15
>>> abs_temperature = c_to_kelvin     ?---  将c_to_kelvin函数赋给变量
>>> abs_temperature(0)
273.15

函数可以被放入列表、元组或字典中:

>>> t = {'FtoK': f_to_kelvin, 'CtoK': c_to_kelvin}     ?---  ?
>>> t['FtoK'](32)       ?---  访问字典中的f_to_kelvin函数
273.15
>>> t['CtoK'](0)      ?---  访问字典中的c_to_kelvin函数
273.15

引用函数的变量,用起来与函数完全相同?。最后一个例子演示了如何使用字典调用各个函数,只要通过用作字符串键的值即可。在需要根据字符串值选择不同函数的情况下,这种模式就很常用。很多时候,这种用法代替了C和Java等语言中的switch结构。

9.6 lambda表达式

上面那种简短的函数,还可以用lambda表达式来定义:

lambda parameter1, parameter2, . . .: expression

lambda表达式是匿名的小型函数,可以快速地在行内完成定义。通常小型函数是要被传给另一个函数的,例如,列表的排序方法用到的键函数。这种情况下,通常没有必要定义一个大型函数,而且在使用的地方以外定义也会显得很别扭。上一节中的字典就可以在一处完成全部定义:

>>> t2 = {'FtoK': lambda deg_f: 273.15 + (deg_f - 32) * 5 / 9,
...       'CtoK': lambda deg_c: 273.15 + deg_c}     ?---  ?
>>> t2['FtoK'](32)
273.15

以上示例将lambda表达式定义为字典值?。注意,lambda表达式没有return语句,因为表达式的值将自动返回。

9.7 生成器函数

生成器(generator)函数是一种特殊的函数,可用于定义自己的迭代器(iterator)。在定义生成器函数时,用关键字yield返回每一个迭代值。当没有可迭代值,或者遇到空的return语句或函数结束时,生成器函数将停止返回值。与普通的函数不同,生成器函数中的局部变量值会保存下来,从本次调用保留至下一次调用:

>>> def four():
...     x = 0     ?---  将x的初始值设为0
...     while x < 4:
...         print("in generator, x =", x)
...         yield x     ?---  返回x的当前值
...         x += 1     ?---  x递增1
...
>>> for i in four():
...       print(i)
...
in generator, x = 0
0
in generator, x = 1
1
in generator, x = 2
2
in generator, x = 3
3

注意,以上生成器函数包含一个while循环,限定了生成器执行的次数。根据使用方式的不同,调用无停止条件的生成器函数可能会导致无限循环。

yield与yield from的对比


从Python 3.3开始,除yield之外,为生成器函数新增了关键字yield from。从本质上说,yield from使将生成器函数串联在一起成为可能。yield from的执行方式与yield相同,但是会将当前生成器委托(delegate)给子生成器。简单一点的话,可以如下使用:

>>> def subgen(x): ... for i in range(x): ... yield i ... >>> def gen(y): ... yield from subgen(y) ... >>> for q in gen(6): ... print(q) ... 0 1 2 3 4 5

以上示例允许将yield表达式移出主生成器,方便了代码重构。

还可以对生成器函数使用in,以便检查某值是否属于生成器生成的一系列值:

>>> 2 in four() in generator, x = 0 in generator, x = 1 in generator, x = 2 True >>> 5 in four() in generator, x = 0 in generator, x = 1 in generator, x = 2 in generator, x = 3 False


速测题:生成器函数 如果要让上面代码中的four()函数适用于任何数字,需要如何修改代码呢?还需要添加什么代码,以便能同时设置起始值呢?

9.8 装饰器

如上所述,因为函数是Python的一级对象(first-class),所以能被赋给变量。函数也可以作为实参传递给其他函数,还可作为其他函数的返回值回传。

例如,可以编写一个Python函数,它把其他函数作为形参,并将这个形参包入另一个执行相关操作的新函数中,然后返回这个新函数。这个新的函数组合可用于替换原来的函数:

>>> def decorate(func):
...     print("in decorate function, decorating", func.__name__)
...     def wrapper_func(*args):
...         print("Executing", func.__name__)
...         return func(*args)
...     return wrapper_func
...   
>>> def myfunction(parameter):
...     print(parameter)
...   
>>> myfunction = decorate(myfunction)
in decorate function, decorating myfunction
>>> myfunction("hello")
Executing myfunction
hello

装饰器(decorator)就是上述过程的语法糖(syntactic sugar),只增加一行代码就可以将一个函数包装到另一个函数中去。效果与上述代码完全相同,不过最终的代码则更加清晰易懂。

装饰器用起来十分简单,由两部分组成:先定义用于包装或“装饰”其他函数的装饰器函数;然后立即在被包装函数的定义前面,加上“@”和装饰器函数名。这里的装饰器函数应该是以一个函数为形参,返回值也是一个函数,如下所示:

>>> def decorate(func):
...     print("in decorate function, decorating", func.__name__)     ?---  ?
...     def wrapper_func(*args):
...         print("Executing", func.__name__)
...         return func(*args)
...     return wrapper_func     ?---  ?
...   
>>> @decorate     ?---  ?
... def myfunction(parameter):
...     print(parameter)
...   
in decorate function, decorating myfunction           
>>> myfunction("hello")     ?---  ?
Executing myfunction
hello

当定义要包装的函数时,上面的decorate函数会把该函数的名称打印出来?。装饰器函数最后将会返回包装后的函数?。通过使用@decorate,myfunction就被装饰了起来?。被包装的函数将会在装饰器函数执行完毕后调用?。

装饰器可将一个函数封装到另一个函数中,这样就可以方便地实现很多目标了。在Django之类的Web框架中,装饰器用于确保用户在执行函数之前已经处于登录状态了。在图形库中,装饰器可用来向图形框架中注册函数。

动手题:装饰器 请修改上述装饰器函数的代码,移除无用的消息,并把被包装函数的返回值用<html>和</html>包起来,以便myfunction("hello")能返回<html>hello<html>。


研究题9:函数的充分利用 回顾第6章和第7章的研究题,请将代码重构为清洗和处理数据的函数。目标应该是将大部分逻辑移入函数中。请自行决定函数和参数的类型,但请牢记每个函数只应完成一项功能,而且不应该产生能影响函数外部环境的副作用。

9.9 小结

  • 在函数内部,可以使用global语句访问外部变量。
  • 实参的传递可以根据位置,也可以根据形参的名称。
  • 函数形参可以有默认值。
  • 函数可以把多个实参归入元组,以便能定义实参数量不定的函数。
  • 函数可以把多个实参归入字典,以便能定义实参数量不定的函数,其中实参按照形参的名称传入。
  • 函数是Python的一级对象,也就是说函数可以被赋给变量,可以通过变量来访问,可以被装饰。

本文摘自《Python快速入门》

本书是一本Python快速入门书,充分体现了Naomi的简约教学风格,确保你有一本随手可翻的Python提要,而且这些重点内容都是Python编程的坚实基础。更为重要的是,本书能让你获得对Python足够的理解和背景知识,以便自主而高效地动手实践。有了本书,在成长为Python开发人员的道路上,你将知道该做什么、去哪里寻找答案、遇到困难时该问什么问题。

Naomi的书正是体现Python风格的典范:优美胜于丑陋,简单胜于复杂,注重可读性。

相关推荐

“版本末期”了?下周平衡补丁!国服最强5套牌!上分首选

明天,酒馆战棋就将迎来大更新,也聊了很多天战棋相关的内容了,趁此机会,给兄弟们穿插一篇构筑模式的卡组推荐!老规矩,我们先来看10职业胜率。目前10职业胜率排名与一周前基本类似,没有太多的变化。平衡补丁...

VS2017 C++ 程序报错“error C2065:“M_PI”: 未声明的标识符&quot;

首先,程序中头文件的选择,要选择头文件,在文件中是没有对M_PI的定义的。选择:项目——>”XXX属性"——>配置属性——>C/C++——>预处理器——>预处理器定义,...

东营交警实名曝光一批酒驾人员名单 88人受处罚

齐鲁网·闪电新闻5月24日讯酒后驾驶是对自己和他人生命安全极不负责的行为,为守护大家的平安出行路,东营交警一直将酒驾作为重点打击对象。5月23日,东营交警公布最新一批饮酒、醉酒名单。对以下驾驶人醉酒...

Qt界面——搭配QCustomPlot(qt platform)

这是我第一个使用QCustomPlot控件的上位机,通过串口精确的5ms发送一次数据,再将读取的数据绘制到图表中。界面方面,尝试卡片式设计,外加QSS简单的配了个色。QCustomPlot官网:Qt...

大话西游2分享赢取种族坐骑手办!PK趣闻录由你书写

老友相聚,仗剑江湖!《大话西游2》2021全民PK季4月激燃打响,各PK玩法鏖战齐开,零门槛参与热情高涨。PK季期间,不仅各种玩法奖励丰厚,参与PK趣闻录活动,投稿自己在PK季遇到的趣事,还有机会带走...

测试谷歌VS Code AI 编程插件 Gemini Code Assist

用ClaudeSonnet3.7的天气测试编码,让谷歌VSCodeAI编程插件GeminiCodeAssist自动编程。生成的文件在浏览器中的效果如下:(附源代码)VSCode...

顾爷想知道第4.5期 国服便利性到底需优化啥?

前段时间DNF国服推出了名为“阿拉德B计划”的系列改版计划,截至目前我们已经看到了两项实装。不过关于便利性上,国服似乎还有很多路要走。自从顾爷回归DNF以来,几乎每天都在跟我抱怨关于DNF里面各种各样...

掌握Visual Studio项目配置【基础篇】

1.前言VisualStudio是Windows上最常用的C++集成开发环境之一,简称VS。VS功能十分强大,对应的,其配置系统较为复杂。不管是对于初学者还是有一定开发经验的开发者来说,捋清楚VS...

还嫌LED驱动设计套路深?那就来看看这篇文章吧

随着LED在各个领域的不同应用需求,LED驱动电路也在不断进步和发展。本文从LED的特性入手,推导出适合LED的电源驱动类型,再进一步介绍各类LED驱动设计。设计必读:LED四个关键特性特性一:非线...

Visual Studio Community 2022(VS2022)安装图文方法

直接上步骤:1,首先可以下载安装一个VisualStudio安装器,叫做VisualStudioinstaller。这个安装文件很小,很快就安装完成了。2,打开VisualStudioins...

Qt添加MSVC构建套件的方法(qt添加c++11)

前言有些时候,在Windows下因为某些需求需要使用MSVC编译器对程序进行编译,假设我们安装Qt的时候又只是安装了MingW构建套件,那么此时我们该如何给现有的Qt添加一个MSVC构建套件呢?本文以...

Qt为什么站稳c++GUI的top1(qt c)

为什么现在QT越来越成为c++界面编程的第一选择,从事QT编程多年,在这之前做C++界面都是基于MFC。当时为什么会从MFC转到QT?主要原因是MFC开发界面想做得好看一些十分困难,引用第三方基于MF...

qt开发IDE应该选择VS还是qt creator

如果一个公司选择了qt来开发自己的产品,在面临IDE的选择时会出现vs或者qtcreator,选择qt的IDE需要结合产品需求、部署平台、项目定位、程序猿本身和公司战略,因为大的软件产品需要明确IDE...

Qt 5.14.2超详细安装教程,不会来打我

Qt简介Qt(官方发音[kju:t],音同cute)是一个跨平台的C++开库,主要用来开发图形用户界面(GraphicalUserInterface,GUI)程序。Qt是纯C++开...

Cygwin配置与使用(四)——VI字体和颜色的配置

简介:VI的操作模式,基本上VI可以分为三种状态,分别是命令模式(commandmode)、插入模式(Insertmode)和底行模式(lastlinemode),各模式的功能区分如下:1)...

取消回复欢迎 发表评论: