函数与模块
函数
函数定义
函数是一段可重复使用的代码块,用于执行特定任务。在 Python 中,函数通过 def
关键字定义。
示例:
def greet(name):
return "Hello, " + name
函数调用
要调用函数,只需使用函数名并提供所需的参数。
示例:
result = greet("Alice")
print(result) # 输出:Hello, Alice
函数参数
函数可以接受参数,这些参数可以在函数内部使用。
示例:
def add_numbers(a, b):
return a + b
函数嵌套定义
在 Python 中,可以在一个函数内定义另一个函数,这称为函数嵌套。
示例:
def outer_function():
def inner_function():
return "Inside inner function"
return inner_function()
Lambda函数
Lambda 函数是一种匿名函数,用于简单的函数操作。
示例:
add = lambda a, b: a + b
print(add(3, 4)) # 输出:7
递归函数
递归函数是调用自身的函数。
示例:
def factorial(n):
if n == 0:
return 1
return n * factorial(n-1)
函数列表
在 Python 中,函数也可以存储在列表中,并通过索引进行调用。
示例:
def say_hello():
print("Hello!")
def say_goodbye():
print("Goodbye!")
function_list = [say_hello, say_goodbye]
function_list[0]() # 输出:Hello!
变量作用域
在 Python 中,变量的作用域分为局部作用域和全局作用域。在函数内部定义的变量通常是局部变量,只在函数内部有效。全局变量定义在函数外部,可以在整个程序中访问。
示例:
global_var = 10
def my_function():
local_var = 20
print(global_var) # 可以访问全局变量
print(local_var) # 可以访问局部变量
my_function()
print(global_var) # 输出: 10
模块
模块是包含 Python 定义和语句的文件,可以被其他程序引入。要使用模块中的函数或变量,可以使用 import
语句导入模块。
示例:
import math
print(math.sqrt(16)) # 输出: 4.0
模块包
模块包是包含模块的文件夹,可以通过在文件夹中放置一个名为 __init__.py
的文件来将其定义为包。包可以包含多个模块,使代码更有组织性。
示例:
my_package/
__init__.py
module1.py
module2.py
库函数的实现
Python 的标准库提供了许多常用的库函数,例如 math
、random
、os
等。这些库函数是用 C 语言实现的,通过 Python 的 C API 与 Python 解释器交互。
示例:
import math
print(math.sqrt(25)) # 使用 math 库中的平方根函数
变量作用域
有哪些作用域
在 Python 中,变量的作用域分为以下几种:
-
局部作用域(Local scope):变量在函数内部定义,只能在该函数内部访问。
-
全局作用域(Global scope):变量在函数外部定义,可以在整个程序中访问。
-
嵌套作用域(Enclosing scope):变量在函数内部嵌套函数中定义,可以在外层函数和内层函数中访问。
global 语句
global
关键字用于在函数内部声明变量在全局作用域中定义,从而可以在函数内部修改全局变量的值。
示例:
x = 10
def modify_global():
global x
x = 20
modify_global()
print(x) # 输出:20
nonlocal 语句
nonlocal
关键字用于在函数内部声明变量在嵌套作用域中定义,从而可以在内层函数中修改外层函数的变量。
示例:
def outer_function():
x = 10
def inner_function():
nonlocal x
x = 20
inner_function()
print(x) # 输出:20
outer_function()
模块
导入模块
在 Python 中,可以使用 import
语句来导入模块,让你可以使用模块中定义的函数、类和变量。
用import 还是 from
- 使用
import module_name
可以导入整个模块,并使用module_name.function_name
访问模块中的函数或变量。 - 使用
from module_name import function_name
可以只导入模块中的特定函数或变量,直接使用function_name
调用。
重新载入模块
如果你修改了模块的代码,想要重新载入模块,可以使用 importlib.reload(module_name)
函数。
示例:
import importlib
import my_module
# 修改了 my_module 中的代码
importlib.reload(my_module)
模块搜索路径
Python 解释器在导入模块时会按照一定顺序搜索模块,搜索路径包括内置模块、sys.path 中列出的目录以及 PYTHONPATH 环境变量指定的目录。
嵌套导入模块
在模块中可以嵌套导入其他模块,导入的模块会成为当前模块的属性,可以通过点号访问。
查看模块对象属性
可以使用 dir(module_name)
函数来查看模块对象的属性列表。
__name__ 属性和命令参数
__name__
属性是一个特殊的内置属性,当一个模块被直接运行时,其 __name__
属性的值为 '__main__'
;当一个模块被导入时,其 __name__
属性的值为模块名。
隐藏模块数据
在 Python 中,可以使用双下划线 __
开头的变量或函数来隐藏模块数据,这些变量或函数在模块外部无法直接访问。
例如:
__hidden_variable = 42
模块包
包的基本结构
在 Python 中,包是用来组织模块的一种方式,它是一个包含 __init__.py
文件的目录。__init__.py
文件可以为空,也可以包含包的初始化代码。
例如,一个名为 my_package
的包的基本结构如下:
my_package/
__init__.py
module1.py
module2.py
导入包
要导入一个包,可以使用 import package_name
语句。导入包后,可以通过 package_name.module_name
的方式访问包中的模块。
例如,要导入上述的 my_package
包中的 module1
模块,可以这样做:
import my_package.module1
相对导入
相对导入是指在包内部,使用相对路径来导入其他模块。相对导入使用 from .module_name import something
的语法。
例如,在 my_package
包中的 module1
模块想要导入 module2
模块,可以使用相对导入:
from . import module2
需要注意的是,相对导入只能在包内部使用,不能在独立的 Python 文件中使用。
面向对象编程
理解 python 面向对象
Python 的类
类是一种抽象数据类型,用于定义对象的属性和方法。通过类可以创建多个具有相似特征和行为的对象。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
print(f"Hello, my name is {self.name} and I am {self.age} years old.")
# 创建一个 Person 类的对象
person1 = Person("Alice", 30)
person1.greet()
Python 的对象
对象是类的实例,具有类定义的属性和方法。每个对象都是独立的实体,可以通过类来创建和操作。
# 创建一个 Person 类的另一个对象
person2 = Person("Bob", 25)
person2.greet()
在上面的示例中,Person
类定义了人的属性和方法,而 person1
和 person2
是 Person
类的两个不同对象,每个对象都有自己的属性值。
在 Python 中,类是用来创建对象的蓝图,对象是类的实例。类定义了对象的属性和方法。
定义和使用类
定义类
class MyClass:
def __init__(self, name):
self.name = name
def greet(self):
print("Hello, my name is", self.name)
# 创建对象
obj = MyClass("Alice")
使用类
obj.greet() # 输出: Hello, my name is Alice
对象的属性和方法
对象的属性
对象的属性是与对象相关联的数据。在类中,属性通过 self
关键字来定义和访问。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("Alice", 30)
print(p.name) # 输出: Alice
print(p.age) # 输出: 30
对象的方法
对象的方法是与对象相关联的函数。方法在类中定义,第一个参数通常是 self
,表示对象本身。
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
print(self.name, "says woof!")
d = Dog("Buddy")
d.bark() # 输出: Buddy says woof!
类的 “伪私有” 属性和方法
在 Python 中,以双下划线 __
开头的属性和方法被视为“伪私有”,外部无法直接访问。
class Example:
def __init__(self):
self.__private_var = 10
def __private_method(self):
print("This is a private method")
e = Example()
print(e.__private_var) # 会引发错误
e.__private_method() # 会引发错误
构造函数和析构函数
构造函数 __init__
在创建对象时被调用,析构函数 __del__
在对象被销毁时被调用。
class MyClass:
def __init__(self):
print("Object created")
def __del__(self):
print("Object destroyed")
obj = MyClass() # 输出: Object created
del obj # 输出: Object destroyed
Python 中的类继承
在 Python 中,类可以通过继承来获得另一个类的属性和方法。这种机制允许我们创建一个新类(子类),该类可以继承一个或多个已存在的类(父类)的属性和方法。
简单继承示例
# 定义一个父类
class Animal:
def __init__(self, species):
self.species = species
def sound(self):
print("Some generic sound")
# 定义一个子类继承自 Animal
class Dog(Animal):
def __init__(self, name, species):
super().__init__(species)
self.name = name
def sound(self):
print("Woof! Woof!")
# 创建一个 Dog 类的对象
dog = Dog("Buddy", "Canine")
print(f"{dog.name} is a {dog.species}")
dog.sound()
调用父类的构造函数
在子类中,可以使用 super()
函数来调用父类的构造函数,以便在子类中初始化父类的属性。
多重继承
Python 支持多重继承,即一个子类可以继承多个父类的属性和方法。在定义类时,可以在类名后的括号中列出所有要继承的父类。
class A:
def method_a(self):
print("Method A")
class B:
def method_b(self):
print("Method B")
class C(A, B):
def method_c(self):
print("Method C")
# 创建一个 C 类的对象
obj = C()
obj.method_a()
obj.method_b()
obj.method_c()
在上面的示例中,类 C
继承了类 A
和类 B
,因此可以访问这两个父类中的方法。
运算符重载
在Python中,我们可以通过定义特殊方法来重载运算符。这些特殊方法在类中定义,并且以双下划线开始和结束。
加法运算重载
例如,我们可以通过定义 __add__
方法来重载加法运算符 +
。以下是一个例子:
class Complex:
def __init__(self, real, imag):
self.real = real
self.imag = imag
# 重载加法运算符
def __add__(self, other):
return Complex(self.real + other.real, self.imag + other.imag)
def __str__(self):
return f"{self.real} + {self.imag}j"
c1 = Complex(1, 2)
c2 = Complex(2, 3)
c3 = c1 + c2 # 使用重载的加法运算符
print(c3) # 输出: 3 + 5j
索引和分片重载
我们可以通过定义 __getitem__
和 __setitem__
方法来重载索引和切片操作。以下是一个例子:
class MyList:
def __init__(self, data):
self.data = data
# 重载索引操作
def __getitem__(self, index):
return self.data[index]
# 重载分片操作
def __setitem__(self, index, value):
self.data[index] = value
my_list = MyList([1, 2, 3, 4, 5])
print(my_list[1]) # 输出: 2
my_list[1] = 100
print(my_list[1]) # 输出: 100
自定义迭代器对象
在Python中,我们可以通过定义 __iter__
和 __next__
方法来创建自定义的迭代器对象。以下是一个例子:
class MyIterator:
def __init__(self, start, end):
self.value = start
self.end = end
# 返回迭代器对象
def __iter__(self):
return self
# 返回下一个值
def __next__(self):
if self.value >= self.end:
raise StopIteration
current_value = self.value
self.value += 1
return current_value
for i in MyIterator(1, 5):
print(i) # 输出: 1 2 3 4
定制对象的字符串形式
我们可以通过定义 __str__
和 __repr__
方法来定制对象的字符串形式。以下是一个例子:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# 返回友好的字符串表示
def __str__(self):
return f"Person(name={self.name}, age={self.age})"
# 返回官方的字符串表示
def __repr__(self):
return f"Person(name={repr(self.name)}, age={self.age})"
p = Person("John", 30)
print(str(p)) # 输出: Person(name=John, age=30)
print(repr(p)) # 输出: Person(name='John', age=30)