Python 快速入门

文章目录


1. 语言基础

1.1 数据类型与变量

Python 是一门动态类型语言,这意味着你不需要显式声明变量的类型。Python 解释器会根据你赋予变量的值自动推断其类型。这使得 Python 代码简洁易懂,但同时也需要注意一些潜在的问题。

1.1.1 Python 数据类型概述

Python 提供了多种内置数据类型,以下是一些常见的类型:

  • 数值类型:

    • 整型 (int):用于表示整数,例如 10, -5, 0
    • 浮点型 (float):用于表示小数,例如 3.14, -2.5, 0.0
    • 复数类型 (complex):用于表示复数,例如 2+3j
  • 序列类型:

    • 字符串类型 (str):用于表示文本,例如 “Hello world!”, “Python”。
    • 列表类型 (list):有序可变序列,用方括号 [] 包裹,元素之间用逗号 , 分隔。
    • 元组类型 (tuple):有序不可变序列,用圆括号 () 包裹,元素之间用逗号 , 分隔。
  • 集合类型 (set):

    • 无序可变集合,用花括号 {} 包裹,元素之间用逗号 , 分隔,且元素不可重复。
  • 映射类型:

    • 字典类型 (dict):无序可变键值对集合,用花括号 {} 包裹,键值对之间用冒号 : 分隔。
  • 布尔类型 (bool):

    • 用于表示真假,只有 TrueFalse 两种值。
  • 其他类型:

    • NoneType:表示空值,用 None 表示。

1.1.2 变量声明与赋值

在 Python 中,使用 = 符号来给变量赋值。

name = "Alice" 
age = 25 
is_student = True

需要注意的是,变量名必须以字母或下划线开头,后面可以跟字母、数字或下划线。同时,Python 变量名区分大小写。

1.1.3 类型转换

有时我们需要将不同数据类型之间进行转换,Python 提供了一些内置函数来实现类型转换:

  • int():将其他数据类型转换为整型
  • float():将其他数据类型转换为浮点型
  • str():将其他数据类型转换为字符串类型
  • bool():将其他数据类型转换为布尔类型

例如:

number = "10" 
int_number = int(number)  # 将字符串转换为整型

1.2 运算符与表达式

运算符是用来对操作数执行特定操作的符号,表达式则是由操作数和运算符组合而成的计算公式。

1.2.1 算术运算符

算术运算符用于进行数值计算,包括:

运算符描述示例结果
+加法10 + 515
-减法10 - 55
*乘法10 * 550
/除法10 / 52.0
//整数除法10 // 52
%取余10 % 50
**幂运算10 ** 2100

1.2.2 比较运算符

比较运算符用于比较两个操作数的大小或是否相等,结果为布尔值(True 或 False)。

运算符描述示例结果
==等于10 == 5False
!=不等于10 != 5True
>大于10 > 5True
<小于10 < 5False
>=大于等于10 >= 5True
<=小于等于10 <= 5False

1.2.3 逻辑运算符

逻辑运算符用于对布尔值进行操作,包括:

运算符描述示例结果
and逻辑与True and TrueTrue
or逻辑或True or FalseTrue
not逻辑非not TrueFalse

1.2.4 位运算符

位运算符用于对操作数的二进制位进行操作,包括:

运算符描述示例结果
&按位与10 & 50
|按位或10 | 515
^按位异或10 ^ 515
~按位取反~10-11
<<左移10 << 240
>>右移10 >> 22

1.2.5 赋值运算符

赋值运算符用于将值赋给变量,包括:

运算符描述示例等价于
=赋值x = 10x = 10
+=加法赋值x += 5x = x + 5
-=减法赋值x -= 5x = x - 5
*=乘法赋值x *= 5x = x * 5
/=除法赋值x /= 5x = x / 5
//=整数除法赋值x //= 5x = x // 5
%=取余赋值x %= 5x = x % 5
**=幂运算赋值x **= 5x = x ** 5
&=按位与赋值x &= 5x = x & 5
|=按位或赋值x |= 5x = x | 5
^=按位异或赋值x ^= 5x = x ^ 5
<<=左移赋值x <<= 5x = x << 5
>>=右移赋值x >>= 5x = x >> 5

1.2.6 运算符优先级

在表达式中,不同的运算符具有不同的优先级。优先级高的运算符先执行,优先级低的运算符后执行。可以使用括号 () 来改变运算顺序,括号内的表达式优先执行。

以下列出了一些常用运算符的优先级,从高到低排序:

  1. 幂运算 **
  2. 按位取反 ~
  3. 乘法、除法、整数除法、取余 *, /, //, %
  4. 加法、减法 +, -
  5. 位运算 <<, >>, &, ^, |
  6. 比较运算符 ==, !=, >, <, >=, <=
  7. 逻辑运算符 not, and, or
  8. 赋值运算符 =, +=, -=, *=, /=, //= 等等

1.2.7 表达式

表达式是由操作数和运算符组合而成的计算公式, Python 解释器会根据运算符的优先级和结合性来计算表达式的值。

例如:

  • 10 + 5 * 2:由于乘法运算符优先级高于加法运算符,所以先执行 5 * 2,得到结果 10,然后再执行 10 + 10,最终结果为 20。
  • (10 + 5) * 2:由于括号内的表达式优先执行,所以先执行 10 + 5,得到结果 15,然后再执行 15 * 2,最终结果为 30。

1.3 控制流语句

控制流语句允许我们控制程序执行的流程,改变程序的执行顺序。它们使程序能够根据条件做出决策,重复执行代码块,以及在需要时跳出循环。

1.3.1 条件语句 (if-elif-else)

条件语句根据条件判断,选择执行不同的代码块。

语法:

if 条件1:
    代码块1
elif 条件2:
    代码块2
else:
    代码块3
  • if: 如果条件1为真,则执行代码块1。
  • elif: 如果条件1为假,则判断条件2,如果条件2为真,则执行代码块2。可以有多个 elif 语句。
  • else: 如果所有条件都为假,则执行代码块3。else 语句是可选的。

示例:

score = int(input("请输入分数:"))

if score >= 90:
    print("优秀")
elif score >= 80:
    print("良好")
elif score >= 70:
    print("中等")
else:
    print("不及格")

1.3.2 循环语句 (for, while)

循环语句用于重复执行一段代码,直到满足特定条件为止。

for 循环

for 循环用于遍历序列 (例如列表、元组、字符串) 中的每个元素。

语法:

for 变量 in 序列:
    代码块
  • 变量: 用于保存当前迭代的元素值。
  • 序列: 需要遍历的序列。

示例:

names = ["Alice", "Bob", "Charlie"]

for name in names:
    print("Hello, " + name)

while 循环

while 循环会一直执行代码块,直到条件变为假。

语法:

while 条件:
    代码块
  • 条件: 循环的判断条件。

示例:

count = 0

while count < 5:
    print(count)
    count += 1

1.3.3 循环控制语句 (break, continue)

循环控制语句用于在循环中改变执行流程。

break 语句

break 语句用于立即退出循环。

示例:

for i in range(10):
    if i == 5:
        break
    print(i)

continue 语句

continue 语句用于跳过当前迭代,继续执行下一轮循环。

示例:

for i in range(10):
    if i % 2 == 0:
        continue
    print(i)

1.4 函数

函数是 Python 代码的模块化单元,它可以接受输入参数,执行一系列操作,并返回结果。函数可以提高代码的可重用性和可读性,使程序更加模块化和易于维护。

1.4.1 函数定义与调用

函数定义:

def 函数名(参数列表):
    """函数文档字符串"""
    代码块
    return 返回值
  • def: 定义函数的关键字。
  • 函数名: 函数的名称,必须以字母或下划线开头,可以包含字母、数字和下划线。
  • 参数列表: 函数接受的参数列表,多个参数用逗号隔开。
  • 函数文档字符串: 描述函数功能的字符串,可以使用三引号包裹。
  • 代码块: 函数体,包含要执行的代码。
  • return: 返回函数的结果,可以省略,此时函数返回 None。

函数调用:

函数名(参数列表)
  • 函数名: 要调用的函数名称。
  • 参数列表: 传递给函数的参数,顺序和类型要与函数定义中的参数列表一致。

示例:

def greet(name):
    """向用户问好"""
    print("Hello, " + name + "!")

greet("Alice") # 调用 greet 函数,传递参数 "Alice"

1.4.2 函数参数与返回值

参数:

  • 位置参数: 按顺序传递的参数,调用函数时参数的顺序要与函数定义中的参数顺序一致。
  • 关键字参数: 使用参数名和参数值对的形式传递参数,可以改变参数的顺序。
  • 默认参数: 函数定义中为参数指定默认值,如果调用函数时未提供该参数,则使用默认值。
  • 可变参数: 使用 *args 来接收任意数量的位置参数,这些参数会被打包成一个元组。
  • 关键字可变参数: 使用 **kwargs 来接收任意数量的关键字参数,这些参数会被打包成一个字典。

返回值:

  • 函数可以使用 return 语句返回值,返回值可以是任何类型的值,包括数字、字符串、列表、字典等。
  • 如果函数没有 return 语句,则默认返回 None。

示例:

def calculate_sum(a, b=10): # b 为默认参数,默认值为 10
    """计算两个数的和"""
    return a + b

result = calculate_sum(5) # 调用函数,传递一个参数,使用 b 的默认值
print(result) # 输出 15

result = calculate_sum(5, 20) # 调用函数,传递两个参数,覆盖 b 的默认值
print(result) # 输出 25

def sum_all(*args): # 使用 *args 接收任意数量的位置参数
    """计算所有参数的和"""
    total = 0
    for arg in args:
        total += arg
    return total

result = sum_all(1, 2, 3, 4, 5) # 传递多个参数
print(result) # 输出 15

1.4.3 递归函数

递归函数是指在函数内部调用自身的函数。

示例:

def factorial(n):
    """计算 n 的阶乘"""
    if n == 0:
        return 1
    else:
        return n * factorial(n - 1)

result = factorial(5)
print(result) # 输出 120

注意: 递归函数必须有一个终止条件,否则会无限递归下去导致程序崩溃。

1.4.4 匿名函数 (lambda)

匿名函数是指没有名称的函数,使用 lambda 关键字定义。

语法:

lambda 参数列表: 表达式
  • lambda: 定义匿名函数的关键字。
  • 参数列表: 函数的参数列表。
  • 表达式: 函数体,只能包含一个表达式,返回值为该表达式的结果。

示例:

square = lambda x: x * x
print(square(5)) # 输出 25

add = lambda x, y: x + y
print(add(10, 20)) # 输出 30

注意: 匿名函数通常用于简化代码,尤其是在需要使用函数作为参数或返回值的情况下。

2. 数据结构

数据结构是组织和存储数据的特定方式,在编程中扮演着至关重要的角色。Python 提供了多种内置数据结构,让我们可以方便地管理数据。

2.1 列表 (List)

列表是一种有序的可变数据结构,可以存储不同类型的元素。

2.1.1 列表创建与访问

  • 创建列表: 使用方括号 [] 包含元素,元素之间用逗号 , 分隔。

    my_list = [1, 2, 3, "hello", True]
    
  • 访问元素: 使用索引访问列表中的元素,索引从 0 开始。

    print(my_list[0])  # 输出: 1
    print(my_list[3])  # 输出: hello
    
  • 负索引: 负索引从列表末尾开始计数,-1 代表最后一个元素,-2 代表倒数第二个元素,以此类推。

    print(my_list[-1]) # 输出: True
    print(my_list[-3]) # 输出: 3
    

2.1.2 列表操作 (添加、删除、修改)

  • 添加元素:

    • append(x): 在列表末尾添加元素。
    • insert(i, x): 在指定索引 i 处插入元素 x
    • extend(iterable): 将可迭代对象的所有元素添加到列表末尾。
    my_list.append(4)
    my_list.insert(1, "world")
    my_list.extend([5, 6])
    print(my_list) # 输出: [1, 'world', 2, 3, 'hello', True, 4, 5, 6]
    
  • 删除元素:

    • remove(x): 删除第一个值为 x 的元素。
    • pop(i): 删除指定索引 i 处的元素,并返回该元素的值。
    • del list[i]del list[i:j] : 删除指定索引或切片范围内的元素。
    my_list.remove("hello")
    removed_item = my_list.pop(2)
    del my_list[0:2]
    print(my_list) # 输出: [3, True, 4, 5, 6]
    
  • 修改元素: 使用索引直接修改元素的值。

    my_list[0] = "new_value"
    print(my_list) # 输出: ['new_value', True, 4, 5, 6]
    

2.1.3 列表遍历

  • 使用 for 循环遍历:

    for item in my_list:
        print(item)
    
  • 使用索引遍历:

    for i in range(len(my_list)):
        print(my_list[i])
    

2.2 元组 (Tuple)

元组是一种有序的不可变数据结构,使用圆括号 () 包含元素。

2.2.1 元组创建与访问

  • 创建元组: 使用圆括号 () 包含元素,元素之间用逗号 , 分隔。

    my_tuple = (1, 2, "hello", True)
    
  • 访问元素: 使用索引访问元组中的元素,索引从 0 开始。

    print(my_tuple[0])  # 输出: 1
    print(my_tuple[2])  # 输出: hello
    
  • 负索引: 负索引从元组末尾开始计数,-1 代表最后一个元素,-2 代表倒数第二个元素,以此类推。

    print(my_tuple[-1]) # 输出: True
    print(my_tuple[-3]) # 输出: 2
    

2.2.2 元组不可变性

元组是不可变的,这意味着一旦创建,就不能修改其元素。

my_tuple[0] = "new_value" # 会导致错误

2.2.3 元组与列表的区别

特性列表元组
可变性可变不可变
括号[]()
使用场景存储需要修改的数据存储不需要修改的数据
  • 列表适合存储需要频繁添加、删除、修改元素的数据。
  • 元组适合存储不需要修改的数据,例如存储常量、坐标等。

2.3 字典 (Dictionary)

字典是一种无序的键值对集合,使用花括号 {} 包含键值对,键和值之间用冒号 : 分隔,键值对之间用逗号 , 分隔。

2.3.1 字典创建与访问

  • 创建字典: 使用花括号 {} 包含键值对。

    my_dict = {"name": "John", "age": 30, "city": "New York"}
    
  • 访问元素: 使用键访问字典中的值。

    print(my_dict["name"])  # 输出: John
    print(my_dict["age"])  # 输出: 30
    
  • 不存在的键: 访问不存在的键会导致 KeyError 错误。

    print(my_dict["hobby"])  # 抛出 KeyError
    
  • 使用 get() 方法访问: get() 方法可以安全地访问键,如果键不存在,则返回 None 或指定的值。

    print(my_dict.get("hobby"))  # 输出: None
    print(my_dict.get("hobby", "unknown"))  # 输出: unknown
    

2.3.2 字典操作 (添加、删除、修改)

  • 添加元素: 使用新的键和值直接赋值。

    my_dict["hobby"] = "reading"
    print(my_dict)  # 输出: {'name': 'John', 'age': 30, 'city': 'New York', 'hobby': 'reading'}
    
  • 删除元素:

    • del dict[key] : 删除指定键的键值对。
    • pop(key) : 删除指定键的键值对,并返回该键对应的值。
    del my_dict["city"]
    print(my_dict)  # 输出: {'name': 'John', 'age': 30, 'hobby': 'reading'}
    
    city = my_dict.pop("hobby")
    print(my_dict)  # 输出: {'name': 'John', 'age': 30}
    print(city)  # 输出: reading
    
  • 修改元素: 使用键直接修改值。

    my_dict["age"] = 31
    print(my_dict)  # 输出: {'name': 'John', 'age': 31, 'hobby': 'reading'}
    

2.3.3 字典遍历

  • 遍历键: 使用 for key in dict.keys() 遍历字典的所有键。

    for key in my_dict.keys():
        print(key)  # 输出: name, age, hobby
    
  • 遍历值: 使用 for value in dict.values() 遍历字典的所有值。

    for value in my_dict.values():
        print(value)  # 输出: John, 31, reading
    
  • 遍历键值对: 使用 for key, value in dict.items() 遍历字典的所有键值对。

    for key, value in my_dict.items():
        print(f"{key}: {value}")  # 输出: name: John, age: 31, hobby: reading
    

2.4 集合 (Set)

集合是一种无序的、不可重复的元素集合,使用花括号 {} 包含元素,元素之间用逗号 , 分隔。

2.4.1 集合创建与访问

  • 创建集合: 使用花括号 {} 包含元素。
    注意:空集合必须使用 set() 函数创建。

    my_set = {1, 2, 3, 4}
    empty_set = set()
    
  • 访问元素: 集合是无序的,无法通过索引访问元素。可以判断元素是否存在于集合中:

    print(1 in my_set)  # 输出: True
    print(5 in my_set)  # 输出: False
    

2.4.2 集合操作 (交集、并集、差集)

  • 交集: 使用 &intersection() 方法求两个集合的交集。

    set1 = {1, 2, 3}
    set2 = {2, 3, 4}
    intersection_set = set1 & set2
    print(intersection_set)  # 输出: {2, 3}
    
  • 并集: 使用 |union() 方法求两个集合的并集。

    union_set = set1 | set2
    print(union_set)  # 输出: {1, 2, 3, 4}
    
  • 差集: 使用 -difference() 方法求两个集合的差集。

    difference_set = set1 - set2
    print(difference_set)  # 输出: {1}
    

2.4.3 集合的不可重复性

集合中的元素是唯一的,不允许重复。

my_set = {1, 2, 2, 3}
print(my_set)  # 输出: {1, 2, 3}

3. 面向对象编程

面向对象编程 (OOP) 是一种编程范式,它将程序视为一组相互作用的对象,每个对象都包含数据和操作这些数据的函数。OOP 帮助组织和管理大型程序,使其更容易维护和扩展。

3.1 类与对象

3.1.1 类定义

  • 是对象的蓝图,它定义了对象的属性和方法。

  • 在 Python 中,使用 class 关键字定义类,后面跟着类名和冒号:

    class Dog:
      # 类体
    
  • 类体包含了类的属性和方法的定义。

3.1.2 对象创建

  • 对象 是类的实例,它拥有类定义的属性和方法。

  • 在 Python 中,使用类名和括号创建对象:

    my_dog = Dog()
    
  • 这行代码创建了一个名为 my_dogDog 类对象。

3.1.3 属性与方法

  • 属性 是对象的特征,通常用变量表示。

  • 方法 是对象的行为,通常用函数表示。

    class Dog:
      def __init__(self, name, breed):
        self.name = name
        self.breed = breed
    
      def bark(self):
        print(f"{self.name} barks!")
    
  • __init__ 方法是构造函数,用于初始化对象属性。

  • self 参数表示当前对象,用于访问对象的属性和方法。

  • bark 方法定义了狗叫的行为。

3.1.3 实例化和调用类的方法

class Dog:
  def __init__(self, name, breed):
    self.name = name
    self.breed = breed

  def bark(self):
    print(f"{self.name} barks!")

my_dog = Dog("Buddy", "Golden Retriever")
print(f"My dog's name is {my_dog.name} and it's a {my_dog.breed}.")
my_dog.bark()

3.2 封装

封装是面向对象编程中的一个重要概念,它将数据和操作数据的方法捆绑在一起,形成一个独立的、自包含的单元,即对象。封装的目标是隐藏对象的内部实现细节,只对外暴露必要的接口,以控制对对象的访问。

3.2.1 类

类是封装的核心概念,它定义了对象的属性和方法。属性表示对象的特征,方法表示对象的行为。

class Dog:
    def __init__(self, name, breed):
        self.name = name
        self.breed = breed

    def bark(self):
        print("Woof!")

my_dog = Dog("Buddy", "Golden Retriever")
print(my_dog.name)  # 输出:Buddy
my_dog.bark()      # 输出:Woof!

3.2.2 私有属性和方法

  • 使用双下划线 __ 开头的属性和方法被认为是私有的,只能在类内部访问。
  • 私有属性和方法有助于隐藏实现细节,防止外部代码误操作。
class Dog:
    def __init__(self, name, breed):
        self.name = name
        self.__breed = breed  # 私有属性

    def bark(self):
        print("Woof!")

    def __private_method(self):  # 私有方法
        print("This is a private method.")

my_dog = Dog("Buddy", "Golden Retriever")
print(my_dog.name)  # 可以访问公有属性
# print(my_dog.__breed)  # AttributeError: private access
my_dog.bark()  # 可以调用公有方法
# my_dog.__private_method()  # AttributeError: private access

注意: 虽然 Python 的私有机制是通过名称改写来实现的,仍然可以通过一些技巧来访问私有属性和方法。例如,使用 _ClassName__attribute_name 或者 _ClassName__method_name 可以访问私有属性和方法。

# 通过名称改写访问私有属性
print(my_dog._Dog__breed)  # 输出:Golden Retriever

# 通过名称改写访问私有方法
my_dog._Dog__private_method()  # 输出:This is a private method.

3.2.3 属性装饰器

  • Python 中可以使用 @property 装饰器将方法转换为属性,允许开发者通过类似访问属性的方式来调用方法。
  • 同时,可以使用 @name.setter@name.deleter 装饰器来定义属性的 setter 和 deleter 方法,分别用于设置和删除属性的值。
  • 使用属性装饰器可以更方便地控制对属性的访问,并隐藏内部实现细节。
class Dog:
    def __init__(self, name, breed):
        self._name = name
        self._breed = breed

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value

    @name.deleter
    def name(self):
        del self._name

my_dog = Dog("Buddy", "Golden Retriever")
print(my_dog.name) # 输出:Buddy
my_dog.name = "Max"
print(my_dog.name) # 输出:Max
del my_dog.name
# print(my_dog.name)  # AttributeError: 'Dog' object has no attribute 'name'

3.2.4 模块和包

  • 模块: 模块是包含 Python 代码的独立文件,可以将相关的代码封装在一起,方便管理和重用。
  • 包: 包是包含多个模块的文件夹,可以将多个相关的模块组织在一起,方便大型项目管理。
# 模块
# my_module.py
def greet(name):
    print(f"Hello, {name}!")

# 使用模块
import my_module
my_module.greet("Alice")

# 包
# package/__init__.py
# package/module1.py
# package/module2.py
# ...

# 使用包
from package import module1
module1.some_function()

模块和包可以有效地隐藏内部实现细节,提高代码可读性和可维护性。

3.3 继承

继承是面向对象编程中重要的概念之一,它允许创建一个新的类(子类)继承另一个类的属性和方法(父类),从而实现代码复用和扩展。

3.3.1 单继承

单继承是指一个子类只继承一个父类。使用 class 子类名(父类名): 语法实现单继承。

class Animal:
    """
    定义一个动物类
    """

    def __init__(self, name):
        self.name = name

    def speak(self):
        print("Animal sound")

class Dog(Animal):
    """
    定义一个狗类,继承自 Animal 类
    """

    def speak(self):
        print("Woof!")

my_dog = Dog("Buddy")
my_dog.speak()  # 输出 "Woof!"

Dog 类中,我们使用 Animal 作为父类进行继承。子类 Dog 可以访问父类 Animal 中的属性和方法。需要注意的是,子类 Dog 重写了父类的 speak 方法,实现了特定于狗的行为。

3.3.2 多继承

多继承是指一个子类可以继承多个父类。使用 class 子类名(父类1, 父类2, ...): 语法实现多继承。

class Flyer:
    """
    定义一个飞行类
    """

    def fly(self):
        print("Flying...")

class Swimmer:
    """
    定义一个游泳类
    """

    def swim(self):
        print("Swimming...")

class Duck(Flyer, Swimmer):
    """
    定义一个鸭子类,继承自 Flyer 和 Swimmer 类
    """

    def quack(self):
        print("Quack!")

my_duck = Duck()
my_duck.fly()  # 输出 "Flying..."
my_duck.swim()  # 输出 "Swimming..."
my_duck.quack()  # 输出 "Quack!"

Duck 类中,我们继承了 FlyerSwimmer 类。Duck 类可以访问这两个父类的属性和方法。多继承可以实现更加复杂的类关系,但需要注意的是,多继承可能会导致一些复杂的问题,例如方法名冲突和菱形继承问题。

注意:

  • 子类可以重写父类的方法,实现特定于子类的行为。
  • 多继承可能会导致一些复杂的问题,例如方法名冲突和菱形继承问题。

3.4 多态

多态是面向对象编程中的一个重要概念,它指的是同一个操作在不同的对象上表现出不同的行为。这使得代码更加灵活、可扩展和易于维护。

3.4.1 方法重写

方法重写是实现多态的一种方式。子类可以重写父类的方法,实现特定于子类的行为。

示例:

class Animal:
    def speak(self):
        print("Animal sound")

class Dog(Animal):
    def speak(self):
        print("Woof!")

class Cat(Animal):
    def speak(self):
        print("Meow!")

animals = [Dog(), Cat(), Animal()]
for animal in animals:
    animal.speak()  # 输出 "Woof!", "Meow!", "Animal sound"

在上面的例子中,DogCat 类都重写了 Animal 类的 speak 方法,实现了各自不同的声音。通过循环遍历 animals 列表,调用每个对象的 speak 方法,我们可以看到不同的对象表现出不同的行为。

方法重写的规则:

  • 子类方法的名称必须与父类方法的名称相同。
  • 子类方法的参数列表必须与父类方法的参数列表相同。
  • 子类方法的返回值类型必须与父类方法的返回值类型相同或兼容。
  • 子类方法的访问权限必须与父类方法的访问权限相同或更宽松。

3.4.2 多态的应用场景

多态在面向对象编程中有着广泛的应用场景,例如:

  • 代码复用: 通过重写父类的方法,可以实现不同类型的对象共享同一个接口,而无需编写重复的代码。
  • 可扩展性: 通过继承和方法重写,可以轻松地添加新的对象类型,而无需修改现有代码。
  • 代码简洁: 多态可以使代码更加简洁,避免重复的条件判断。
  • 易于维护: 多态可以提高代码的可读性和可维护性,使代码更容易理解和修改。

示例:

假设我们要开发一个游戏,其中包含不同的角色,例如战士、法师和弓箭手。我们可以使用多态来实现角色的行为,例如攻击、防御和技能。

class Character:
    def attack(self):
        print("General attack")

class Warrior(Character):
    def attack(self):
        print("Warrior attack with sword")

class Mage(Character):
    def attack(self):
        print("Mage attack with magic")

characters = [Warrior(), Mage(), Character()]
for character in characters:
    character.attack()  # 输出 "Warrior attack with sword", "Mage attack with magic", "General attack"

通过多态,我们可以用统一的方式处理不同角色的攻击行为,而无需关心角色的具体类型。

4. 常用模块

模块是 Python 代码的组织单元,它可以包含函数、类、变量等。使用模块可以提高代码的可重用性和可维护性。

4.1 模块导入

在 Python 中,可以使用 import 语句导入模块。

4.1 导入整个模块

import math

print(math.pi)
print(math.sqrt(25))

这将导入 math 模块,并使用 math.pimath.sqrt() 访问模块中的常量和函数。

4.2 导入特定属性

from math import pi, sqrt

print(pi)
print(sqrt(25))

这将只导入 math 模块中的 pisqrt 属性,并直接使用它们。

4.3 导入模块并指定别名

import math as m

print(m.pi)
print(m.sqrt(25))

这将导入 math 模块并将其指定为 m,可以使用 m.pim.sqrt() 访问模块中的属性。

4.4 导入所有属性

from math import *

print(pi)
print(sqrt(25))

这将导入 math 模块中的所有属性,但建议不要使用这种方式,因为它会导致命名冲突。

4.5 模块搜索路径

Python 在导入模块时会搜索以下路径:

  • 当前目录
  • 环境变量 PYTHONPATH 中指定的目录
  • 标准库目录

4.2 常用模块介绍

以下是几个 Python 中常用的模块的介绍:

4.2.1 math 模块

math 模块提供了大量的数学函数和常量,可以帮助我们进行各种数学运算。

常用函数:

  • pi: 圆周率
  • sqrt(x): 求平方根
  • pow(x, y): 求 x 的 y 次方
  • sin(x), cos(x), tan(x): 三角函数
  • ceil(x): 向上取整
  • floor(x): 向下取整
  • log(x): 自然对数
  • log10(x): 以 10 为底的对数

示例:

import math

print(math.pi)  # 输出圆周率
print(math.sqrt(25))  # 输出 5
print(math.pow(2, 3))  # 输出 8
print(math.sin(math.pi / 2))  # 输出 1
print(math.ceil(3.14))  # 输出 4
print(math.floor(3.14))  # 输出 3

4.2.2 random 模块

random 模块提供了生成随机数的功能,可以用于各种场景,例如模拟随机事件、洗牌等。

常用函数:

  • random(): 生成 0 到 1 之间的随机浮点数
  • randint(a, b): 生成 a 到 b 之间的随机整数
  • choice(seq): 从序列中随机选择一个元素
  • shuffle(seq): 打乱序列的元素顺序
  • sample(seq, k): 从序列中随机抽取 k 个元素

示例:

import random

print(random.random())  # 输出 0 到 1 之间的随机浮点数
print(random.randint(1, 10))  # 输出 1 到 10 之间的随机整数
print(random.choice(["apple", "banana", "orange"]))  # 输出 "apple", "banana" 或 "orange" 之一
numbers = [1, 2, 3, 4, 5]
random.shuffle(numbers)  # 打乱 numbers 列表的元素顺序
print(numbers)
print(random.sample(numbers, 2))  # 从 numbers 列表中随机抽取 2 个元素

4.2.3 os 模块

os 模块提供了与操作系统交互的功能,可以用来执行操作系统命令、操作文件和目录等。

常用函数:

  • getcwd(): 获取当前工作目录
  • chdir(path): 改变工作目录
  • listdir(path): 列出指定目录下的所有文件和子目录
  • mkdir(path): 创建目录
  • makedirs(path): 创建多级目录
  • remove(path): 删除文件
  • rmdir(path): 删除空目录
  • rename(old_path, new_path): 重命名文件或目录
  • system(command): 执行操作系统命令
  • environ: 获取环境变量字典

示例:

import os

print(os.getcwd())  # 输出当前工作目录
os.chdir("/tmp")  # 改变工作目录到 /tmp
print(os.listdir("/tmp"))  # 列出 /tmp 目录下的所有文件和子目录
os.mkdir("/tmp/mydir")  # 创建目录 /tmp/mydir
os.remove("/tmp/mydir/myfile.txt")  # 删除文件 /tmp/mydir/myfile.txt
os.rename("/tmp/mydir", "/tmp/mynewdir")  # 重命名目录 /tmp/mydir 为 /tmp/mynewdir
os.system("ls -l")  # 执行 ls -l 命令
print(os.environ["HOME"])  # 输出环境变量 HOME 的值

4.2.4 datetime 模块

datetime 模块提供了与日期和时间相关的功能,可以用来创建、格式化、计算日期和时间等。

常用类:

  • datetime.date: 表示日期
  • datetime.time: 表示时间
  • datetime.datetime: 表示日期和时间

常用方法:

  • now(): 获取当前日期和时间
  • today(): 获取当前日期
  • strftime(format): 格式化日期和时间
  • strptime(string, format): 解析日期和时间字符串

示例:

import datetime

now = datetime.datetime.now()  # 获取当前日期和时间
print(now)
print(now.strftime("%Y-%m-%d %H:%M:%S"))  # 格式化日期和时间
birthday = datetime.date(1990, 1, 1)  # 创建日期对象
print(birthday)
date_str = "2023-04-01"
date = datetime.datetime.strptime(date_str, "%Y-%m-%d").date()  # 解析日期字符串
print(date)

4.2.5 requests 模块

requests 模块提供了与网络请求相关的功能,可以用来发送 HTTP 请求、获取网页内容等。

常用方法:

  • get(url): 发送 GET 请求
  • post(url, data): 发送 POST 请求
  • put(url, data): 发送 PUT 请求
  • delete(url): 发送 DELETE 请求
  • json(): 获取响应内容的 JSON 格式
  • text: 获取响应内容的文本格式
  • status_code: 获取响应状态码

示例:

import requests

response = requests.get("https://www.google.com")  # 发送 GET 请求
print(response.status_code)  # 输出响应状态码
print(response.text)  # 输出响应内容的文本格式
response = requests.post("https://www.example.com/api/login", data={"username": "user", "password": "password"})  # 发送 POST 请求
print(response.json())  # 输出响应内容的 JSON 格式

注意: requests 模块不是 Python 的内置模块,需要使用 pip 安装。

pip install requests

这些只是 Python 中常用的模块的一部分,还有很多其他的模块可以满足各种需求,请参考官方文档或其他学习资源进行更深入的了解。

5. 常见错误与调试

程序员在编写代码时不可避免地会遇到各种错误。了解常见的错误类型、掌握错误处理机制以及调试技巧是编写高质量代码的关键。

5.1 常见错误类型

Python 中常见的错误类型包括:

5.1.1 语法错误 (SyntaxError)

  • 代码结构或语法不符合 Python 规范。
  • 例如:缺少冒号、括号不匹配、变量未定义等。

5.1.2 运行时错误 (RuntimeError)

  • 运行时错误,也称为异常,是在程序执行过程中发生的错误。它们会导致程序无法正常执行,并可能引发崩溃或其他意外行为。

5.1.3 逻辑错误 (Logical Error)

  • 代码逻辑存在问题,导致程序无法正常运行或产生错误结果。
  • 例如:循环条件错误、算法逻辑错误等。

5.1.4 常见的运行时错误类型

  • TypeError

    • 描述:类型错误,发生在操作数的类型不匹配时。
    • 例子:
      print("Hello" + 10)  
      # TypeError: can only concatenate str (not "int") to str
      
  • ValueError

    • 描述:值错误,发生在函数接收了类型正确但值不合法的数据时。
    • 例子:
      int("abc")  
      # ValueError: invalid literal for int() with base 10: 'abc'
      
  • NameError

    • 描述:名称错误,发生在访问未定义的变量时。
    • 例子:
      print(my_variable)  
      # NameError: name 'my_variable' is not defined
      
  • IndexError

    • 描述:索引错误,发生在访问列表、元组或字符串时,索引超出了范围。
    • 例子:
      my_list = [1, 2, 3]
      print(my_list[3])  
      # IndexError: list index out of range
      
  • KeyError

    • 描述:键错误,发生在访问字典时,指定的键不存在。
    • 例子:
      my_dict = {"name": "John"}
      print(my_dict["age"])  # KeyError: 'age'
      
  • AttributeError

    • 描述:属性错误,发生在访问对象不存在的属性时。
    • 例子:
      my_str = "Hello"
      print(my_str.length)  
      # AttributeError: 'str' object has no attribute 'length'
      
  • IOError

    • 描述:输入/输出错误,发生在与文件或网络进行交互时出现问题。
    • 例子:
      with open("nonexistent_file.txt", "r") as f:  
      # IOError: [Errno 2] No such file or directory: 'nonexistent_file.txt'
          content = f.read()
      

注意:

  • 这些错误会在运行时发生,而不是在编译时发生。
  • 使用 try...except 语句可以捕获这些错误并进行处理,从而避免程序崩溃。

通过理解常见的运行时错误类型,可以更有效地编写和调试代码,并确保程序的稳定性和可靠性。

5.2 错误处理机制 (try-except)

try-except 语句是 Python 中强大的错误处理机制,它允许你在程序执行过程中捕获并处理异常。

5.2.1 语法

try:
    # 可能引发错误的代码
except 错误类型1:
    # 处理错误类型1的代码
except 错误类型2:
    # 处理错误类型2的代码
    ...
else:
    # 如果没有错误,执行此代码块
finally:
    # 无论是否发生错误,都会执行此代码块

5.2.2 捕获不同错误类型

try:
    num1 = int(input("请输入第一个数: "))
    num2 = int(input("请输入第二个数: "))
    result = num1 / num2
    print(f"{num1} 除以 {num2} 等于 {result}")
except ZeroDivisionError:
    print("除数不能为零!")
except ValueError:
    print("请输入有效的整数!")
else:
    print("计算成功!")
finally:
    print("程序结束!")

解释:

  • 该代码尝试从用户获取两个整数,并计算它们的商。
  • 如果用户输入的第二个数为 0,则会引发 ZeroDivisionError 异常,程序会捕获该异常并打印错误信息。
  • 如果用户输入的不是整数,则会引发 ValueError 异常,程序会捕获该异常并打印错误信息。
  • 如果没有发生任何异常,程序会成功计算结果并打印。
  • 最后,无论是否发生异常,finally 代码块都会执行,打印 “程序结束!”。

5.2.3 捕获所有错误和错误信息

除了捕获特定类型的错误,还可以使用 Exception 来捕获所有类型的错误。

语法:

try:
    # 可能引发错误的代码
except Exception as e:
    # 处理错误
    print(f"发生错误: {e}")
  • Exception 是所有错误类型的父类,因此使用 Exception 可以捕获所有类型的错误。
  • as e 将错误对象赋值给变量 e,可以方便地获取错误信息。
  • except 代码块中,使用 f-string 格式化输出错误信息。

示例:

try:
    num1 = int(input("请输入第一个数: "))
    num2 = int(input("请输入第二个数: "))
    result = num1 / num2
    print(f"计算结果: {result}")
except Exception as e:
    print(f"发生错误: {e}")
finally:
    print("程序结束")

解释:

  1. 如果输入的两个数都是数字,且除数不为零,程序会正常计算并输出结果。
  2. 如果输入的除数为零,程序会输出 “发生错误: division by zero”。
  3. 如果输入的不是数字,程序会输出 "发生错误: invalid literal for int() with base 10: ‘…’ " (其中 “…” 是用户输入的非数字字符)。
  4. 无论程序是否出错,都会输出 “程序结束”。

其他需要注意的点:

  • 虽然可以使用 Exception 捕获所有类型的错误,但一般建议捕获特定的错误类型,以便更精准地处理错误。
  • 可以使用 e.__class__.__name__ 获取错误类型的名称。

示例:

try:
    # 可能引发错误的代码
except Exception as e:
    print(f"发生错误类型: {e.__class__.__name__}")
    print(f"错误信息: {e}")

5.3 调试技巧

调试是程序员必备技能之一,用于发现并解决代码中的错误。常见的调试技巧包括:

5.3.1 打印调试信息 (print)

在代码中插入 print 语句,打印变量的值或执行流程,帮助定位错误。

def calculate(a, b):
    print(f"a: {a}, b: {b}")
    result = a + b
    print(f"result: {result}")
    return result

calculate(5, 10)

5.3.2 使用调试器 (debugger)

Python 内置的调试器 pdb 可以逐步执行代码,查看变量的值和执行流程。

import pdb

def calculate(a, b):
    pdb.set_trace()  # 设置断点
    result = a + b
    return result

calculate(5, 10)

5.3.3 使用日志 (logging)

将错误信息记录到日志文件中,便于分析和排查问题。

import logging

logging.basicConfig(filename='app.log', level=logging.DEBUG)

def calculate(a, b):
    logging.debug(f"a: {a}, b: {b}")
    result = a + b
    logging.debug(f"result: {result}")
    return result

calculate(5, 10)

5.3.4 使用断言 (assert)

在代码中插入断言,用于验证程序逻辑,一旦断言失败,程序会抛出异常。

def calculate(a, b):
    assert a > 0, "a 必须大于 0"
    result = a + b
    return result

calculate(5, 10)
  • 44
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值