基础

基础 属于 Python

113 个练习

关于 基础

Python 是一门动态强类型编程语言。它通过类型提示,同时采用鸭子类型和渐进类型。命令式、声明式(例如函数式)以及面向对象的编程_风格_都受支持,但在内部,Python 中的一切都是对象。

Python 非常重视代码的可读性,并且(和 Haskell 类似)使用显著缩进来表示函数、方法和类的定义。

Python 由 Guido van Rossum 创建,于 1991 年首次发布。Python 软件基金会负责管理和调配 Python 及 CPython 开发的资源,并通过 Python 增强提案(PEP)接收社区成员对语言变更的提案。

当前版本的完整文档可在 docs.python.org 找到。


这第一个概念将介绍 Python 语言的 4 个主要特性:

  1. 名称赋值(变量与常量),
  2. 函数(def 关键字和 return 关键字),
  3. 注释,以及
  4. 文档字符串。
Note

一般来说,Python 学习轨道的内容、测试和分析器工具都遵循 PEP 8 和 PEP 257 中列出的 Python 代码风格约定,此外还(强烈)建议不要使用单个字母作为变量名。

Python 之禅(PEP 20)和什么是 Pythonic?阐述了更多的设计理念。

在 Python 学习轨道上,变量始终用snake_case书写,常量则用 SCREAMING_SNAKE_CASE

名称赋值(变量与常量)

在 Python 中,创建变量或常量时不使用任何关键字。程序员可以用赋值运算符 = 把名称(也叫_变量_)绑定到任意类型的对象上:<name> = <value>。一个名称在其生命周期内可以被重新赋值(或重新绑定)为不同的值(不同的对象类型)。

例如,my_first_variable 可以用 = 重新赋值很多次,而且每次重新赋值后都可以指向不同的对象类型:

>>> my_first_variable = 1  # my_first_variable bound to an integer object of value one.
>>> my_first_variable = 2  # my_first_variable re-assigned to integer value 2.

>>> print(type(my_first_variable))
<class 'int'>

>>> print(my_first_variable)
2

>>> my_first_variable = "Now, I'm a string." # <--You may re-bind a name to a different object type and value.
>>> print(type(my_first_variable))
<class 'str'>

>>> my_first_variable = 'You can call me "str".' # <--Strings can be declared using single or double quote marks.
>>> print(my_first_variable)
You can call me "str".

>>> import collections
>>> my_first_variable = collections.Counter([1,1,2,3,3,3,4,5,6,7]) # <--Now my_first_variable has been re-bound to a Counter object.
>>> print(type(my_first_variable))
<class 'collections.Counter'>

>>> print(my_first_variable)
Counter({3: 3, 1: 2, 2: 1, 4: 1, 5: 1, 6: 1, 7: 1})

常量

常量是程序中只应赋值一次的名称。它们应该在模块(文件)层级定义,通常对程序中的所有函数和类都可见。使用 SCREAMING_SNAKE_CASE 表示这个名称不应被重新赋值,其值也不应被修改。

# All caps signal that this is intended as a constant.
MY_FIRST_CONSTANT = 16

# Re-assignment will be allowed by the compiler & interpreter,
# but this is VERY strongly discouraged.
# Please don't do this, it could create problems in your program!
MY_FIRST_CONSTANT = "Some other value"

函数

在 Python 中,功能单元被封装在函数里,而函数本身也是对象(真是一路都是乌龟turtles all the way down)。

函数可以单独执行,可以作为实参传给其他函数,可以嵌套,也可以绑定到某个类上。当函数绑定到类名时,它们被称为方法。相关的函数和类(连同它们的方法)可以归到同一个文件或模块中,再部分或整体导入供其他程序使用。

def 关键字开始一个函数定义。每个函数可以在 () 圆括号中带有零个或多个形式形参,后面跟一个 : 冒号。函数_体_的语句从 def 的下一行开始,并且必须_缩进成一个块_:

# The body of a function is indented by 2 spaces & prints the sum of the numbers.
def add_two_numbers(number_one, number_two):
  total = number_one + number_two
  print(total)  

>>> add_two_numbers(3, 4)
7


# Inconsistent indentation in your code blocks will raise an error.
>>> def add_three_numbers_misformatted(number_one, number_two, number_three):
...     result = number_one + number_two + number_three   # This was indented by 4 spaces.
...    print(result)     # <--This was only indented by 3 spaces.
...
...
  File "<stdin>", line 3
    print(result)
    ^
IndentationError: unindent does not match any outer indentation level

函数通过 return 关键字_显式_返回一个值或对象:

# Function definition on first line, explicit return used on final line.
def add_two_numbers(number_one, number_two):
  return number_one + number_two   


# Calling the function in the Python shell returns the sum of the numbers.
>>> add_two_numbers(3, 4)
7

# Assigning the function call to a variable and printing 
# the variable will also return the value.
>>> sum_with_return = add_two_numbers(5, 6)
>>> print(sum_with_return)
11

如果在 return 后面没有_显式_表达式,函数会_隐式_返回 None 对象。None 的细节会在后面的概念中介绍。就本练习和本次讲解而言,None 是一个占位符,表示“什么都没有”或 null:


# This function will return `None`
def square_a_number(number):
    square = number * number
    return # <-- note that this return is not followed by an expression

# Calling the function in the Python shell appears 
# to not return anything at all.
>>> square_a_number(2)
>>>


# Using print() with the function call shows that 
# the function is actually returning the **None** object.
>>> print(square_a_number(2))
None

省略 return 的函数同样会_隐式_返回 None 对象。也就是说,如果你在函数中没有使用 return,Python 会替你返回 None 对象。


# This function omits a return keyword altogether
def add_two_numbers(number_one, number_two):
  result = number_one + number_two

>>> add_two_numbers(5, 7)
>>> print(add_two_numbers(5, 7))
None

# Assigning the function call to a variable and printing 
# the variable will also show None.
>>> sum_without_return = add_two_numbers(5, 6)
>>> print(sum_without_return)
None

调用函数

函数通过其名称后面跟 () 来调用。调用定义在类或模块内部的函数时,使用点号(.)表示法。

>>> def raise_to_power(number, power):
...     return number ** power
...

>>> raise_to_power(3,3) # Invoking the function with the arguments 3 and 3.
27


# A mis-match between the number of parameters and the number of arguments will raise an error.
>>> raise_to_power(4,)
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: raise_to_power() missing 1 required positional argument: 'power'


# Calling methods or functions in classes and modules.
>>> start_text = "my silly sentence for examples."
>>> str.upper(start_text)  # <--Calling the upper() method from the built-in str class on start_text.
'MY SILLY SENTENCE FOR EXAMPLES.'

# Because a string is an instance of the str class, methods can also be called on them "directly".
>>> start_text = "my silly sentence for examples."
>>> start_text.upper()  # <--Calling the upper() method on start_text directly.
'MY SILLY SENTENCE FOR EXAMPLES.'

# Alternatively, we can skip the variable assignment (although this gets messy quick).
>>> "my silly sentence for examples.".upper()
'MY SILLY SENTENCE FOR EXAMPLES.'


# Importing the math module
>>> import math
>>> math.pow(2,4)  # <--Calling the pow() function from the math module.
16.0

注释

Python 中的注释以 # 开头,这个 # 不能是字符串的一部分,注释到行尾结束。和许多其他编程语言不同,Python 不支持多行注释标记。注释块的每一行都必须以 # 字符开头。

注释会被解释器忽略:

# This is a single line comment.

x = "foo"  # This is an in-line comment.

# This is a multi-line
# comment block over multiple lines --
# these should be used sparingly.

文档字符串

函数体的第一条语句可以(但不是必须)是一个文档字符串,它简洁地概述函数或对象的用途。文档字符串用三引号(""")声明,并与代码块保持在相同的缩进层级:

# An example from PEP257 of a multi-line docstring
# reformatted to use Google style non-type hinted docstrings.
# Some additional details can be found in the Sphinx documentation:
# https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html#getting-started

def complex(real=0.0, imag=0.0):
    """Form a complex number.

    Keyword Arguments:
        real (float): The real part of the number (default 0.0)
        imag (float): The imaginary part of the number (default 0.0)
        
    """

    if imag == 0.0 and real == 0.0:
        return complex_zero

文档字符串会被自动化文档工具读取,也可以通过调用函数、方法或类名上的特殊属性 .__doc__ 来获取。对于任何需要文档的程序,无论规模大小,都推荐使用文档字符串,其约定见 PEP257。

文档字符串还可以充当轻量级单元测试,PyTest 可以读取并运行它们,也可以导入 doctest 模块来运行。测试和 doctest 会在后面的概念中介绍。

# An example on a user-defined function using a Google style docstring. 
>>> def raise_to_power(number, power):
    """Raise a number to an arbitrary power.

    Parameters:
        number (int): The base number.
        power (int): The power to raise the base number to.
    
    Returns:
        int: The number raised to the specified power.
    
    Takes a number and raises it to the specified power, returning the result.

    """

    return number ** power
...

# Calling the .__doc__ attribute of the function and printing the result.
>>> print(raise_to_power.__doc__)
Raise a number to an arbitrary power.

Parameters:
    number (int): The base number.
    power (int): The power to raise the base number to.

Returns:
    int: The number raised to the specified power.

Takes a number and raises it to the specified power, returning the result.

...

# Printing the __doc__ attribute of the built-in type: str.
>>> print(str.__doc__)
str(object='') -> str
str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or
errors is specified, then the object must expose a data buffer
that will be decoded using the given encoding and error handler.
Otherwise, returns the result of object.__str__() (if defined)
or repr(object).
encoding defaults to 'utf-8'.
errors defaults to 'strict'.
通过 GitHub 编辑 该链接会在新窗口或标签页中打开

学习 基础