1. 函数
在Python中,函数是一种组织代码的方式,它允许你将一段代码封装起来,并在需要时重复使用。以下是Python函数的基本写法:
使用def关键字定义函数。
指定函数名(遵循Python命名规范)。
在括号内添加参数(如果有的话)。
使用冒号:结束函数定义的头部。
在缩进的代码块中编写函数体。
下面是一个简单的Python函数示例:
# 定义一个函数,计算两个数的和
def add_numbers(a, b):
# 函数体:计算并返回两个数的和
result = a + b
return result
# 调用函数并打印结果
sum = add_numbers(3, 4)
print("The sum is:", sum)
2.变量
在Python中,变量的定义非常简单,不需要事先声明变量的类型。你只需要直接给变量赋值即可。以下是一些定义变量的基本方法:
1.直接赋值:
这是最基本的变量定义方式,你只需要将值赋给一个变量名即可。
x = 10 # 整数
name = "Alice" # 字符串
is_valid = True # 布尔值
2.列表:
使用方括号[]来定义列表。
my_list = [1, 2, 3, 4] # 列表包含四个元素
3.元组:
使用圆括号()来定义元组,元组是不可变的。
my_tuple = (1, 2, 3) # 元组包含三个元素
4.集合:
使用花括号{}来定义集合,集合是无序的且元素唯一。
my_set = {1, 2, 3} # 集合包含三个元素
5.字典:
使用花括号{}来定义字典,字典中的元素是键值对。
my_dict = {'key1': 'value1', 'key2': 'value2'} # 字典包含两个键值对
6.使用类型注解(Python 3.5+):
从Python 3.5开始,你可以使用类型注解来指定变量的类型,这有助于代码的可读性和一些IDE的代码检查。
age: int = 25 # 指定age为整数类型
message: str = "Hello, World!" # 指定message为字符串类型
7.全局变量和局部变量:
在函数内部定义的变量是局部变量,它们只能在函数内部访问。在函数外部定义的变量是全局变量,它们可以在整个程序中访问。
x = 5 # 全局变量
def my_function():
y = 10 # 局部变量
print(x) # 可以访问全局变量x
my_function()
8.动态类型:
Python是动态类型语言,这意味着你可以在程序运行时改变变量的类型。
在Python中,变量名必须遵循以下规则:
变量名必须以字母或下划线开头。
变量名只能包含字母、数字和下划线(A-z, 0-9, 和 _ )。
变量名是区分大小写的。
x = 10 # x是整数
x = "Alice" # x现在是字符串
3.循环
在Python中,循环是一种控制结构,用于重复执行一段代码直到满足某个条件。Python提供了两种主要的循环结构:for循环和while循环。
3.1. for 循环
for循环通常用于遍历序列(如列表、元组、字典、集合和字符串)中的元素。
for 变量 in 序列:
# 循环体
# 遍历列表
fruits = ['apple', 'banana', 'cherry']
for fruit in fruits:
print(fruit)
# 遍历字符串
s = "hello"
for char in s:
print(char)
# 遍历字典(遍历键)
my_dict = {'a': 1, 'b': 2, 'c': 3}
for key in my_dict:
print(key, my_dict[key])
# 使用range()函数遍历数字序列
for i in range(5): # 从0到4
print(i)
3.2. while 循环
while循环根据给定的条件重复执行代码块,直到条件不再为真。
while 条件:
# 循环体
# 计数器控制的循环
count = 0
while count < 5:
print(count)
count += 1 # 增加计数器
# 条件控制的循环
is_active = True
while is_active:
print("用户仍然活跃")
is_active = False # 改变条件以退出循环
3.循环控制语句
Python还提供了两个控制循环的语句:break和continue。
break:立即终止当前循环。
continue:跳过当前循环的剩余部分,并继续下一次迭代。
# 使用break退出循环
for i in range(10):
if i == 5:
break
print(i)
# 使用continue跳过迭代
for i in range(10):
if i % 2 == 0:
continue
print(i)
4. 类的写法
在Python中,类是一种创建对象和封装数据的方式。类定义了一组属性(变量)和方法(函数),这些属性和方法属于创建的对象。以下是Python中定义类的基本步骤:
4.1. 使用class关键字定义类
class MyClass:
# 类体
4.2. 定义类的属性和方法
属性通常是类变量,它们在所有实例之间共享。方法则是类的函数,它们可以访问和修改类的属性。
class Person:
species = 'Homo sapiens' # 类变量
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.")
def celebrate_birthday(self): # 实例方法
self.age += 1
print(f"Happy birthday {self.name}! You are now {self.age} years old.")
4.3. 创建类的实例
使用类名和括号来创建一个类的实例(对象)。
person1 = Person("Alice", 30)
person2 = Person("Bob", 25)
4.4. 访问属性和方法
通过点.操作符来访问实例的属性和方法。
person1.greet() # 输出: Hello, my name is Alice and I am 30 years old.
person1.celebrate_birthday() # 输出: Happy birthday Alice! You are now 31 years old.
4.5. 特殊方法(魔术方法)
Python有一些特殊的方法,它们以双下划线开始和结束(例如__init__),这些方法在特定的操作被调用时自动执行。
__init__:构造器,创建对象时自动调用。
__str__:定义对象的字符串表示。
__del__:析构器,对象被销毁时自动调用。
4.6. 继承
Python支持面向对象编程中的继承特性,允许一个类(子类)继承另一个类(父类)的属性和方法。
class Employee(Person): # Employee继承自Person
def __init__(self, name, age, job_title):
super().__init__(name, age) # 调用父类的构造器
self.job_title = job_title
def describe(self):
print(f"{self.name} is a {self.age} year old {self.species} who works as a {self.job_title}.")
4.6.1. 调用父类构造函数方法
在Python中,super()函数用于调用父类(超类)的一个方法。特别是在构造函数(__init__方法)中,super()可以用来确保父类的构造函数被正确调用,这样可以保证父类被正确初始化。
使用super().init(name, age)确实是一种调用父类构造函数的方式,但这并不是唯一的方式,也不是必须的方式。以下是几种不同的情况:
- 使用super()调用父类构造函数
这是最推荐的方式,特别是在涉及到多重继承时。super()函数会根据方法解析顺序(MRO)来决定调用哪个父类的构造函数。 - 直接调用父类构造函数
在某些情况下,你也可以直接调用父类的构造函数,而不使用super()。这种方式在单继承中是可行的,但在多重继承中可能会导致问题,因为它不会考虑MRO。
class Parent:
def __init__(self, name, age):
print(f"Parent: {name}, {age}")
class Child(Parent):
def __init__(self, name, age):
Parent.__init__(self, name, age)
print("Child")
child = Child("Alice", 30)
输出:
Parent: Alice, 30
Child
- 不调用父类构造函数
在某些情况下,你可能不想调用父类的构造函数。这通常不是一个好的做法,因为它可能会导致父类没有被正确初始化。
class Parent:
def __init__(self, name, age):
print(f"Parent: {name}, {age}")
class Child(Parent):
def __init__(self, name, age):
print("Child")
child = Child("Alice", 30)
输出:
Child
总结
推荐使用super():因为它遵循MRO,适用于多重继承,并且是Python官方推荐的方式。
直接调用父类构造函数:适用于单继承,但在多重继承中可能会导致问题。
不调用父类构造函数:通常不是一个好的做法,因为它可能会导致父类没有被正确初始化。
因此,使用super().init(name, age)是一种安全且推荐的方式,特别是在涉及到继承时。
4.7. 多态
Python支持多态,这意味着子类可以定义与父类同名的方法,这将覆盖父类中的方法。
employee1 = Employee("Charlie", 40, "Developer")
employee1.describe() # 输出: Charlie is a 40 year old Homo sapiens who works as a Developer.
5. self是什么
在Python中,self是一个指向类实例自身的引用。当你定义一个类的方法时,self参数是必需的,它允许你在类的实例方法中访问类的属性和方法。
self的作用
- 访问实例属性:self允许你访问和修改实例的属性。
- 访问实例方法:self允许你从实例方法中调用类的其他方法。
- 区分实例属性和类属性:self帮助你区分实例属性(每个实例都有自己的属性)和类属性(所有实例共享的属性)。
在Python中,每个Person实例可以拥有自己的实例属性,这些属性不仅限于name和age。你可以定义任何数量和类型的实例属性,以满足你的应用需求。以下是如何定义和使用其他实例属性的步骤:
5.1. 定义其他实例属性
在类的__init__方法中,你可以添加更多的参数来定义其他实例属性。例如,我们可以为Person类添加gender和email属性:
class Person:
def __init__(self, name, age, gender, email):
self.name = name
self.age = age
self.gender = gender
self.email = email
def greet(self):
print(f"Hello, my name is {self.name}, I am {self.age} years old, my gender is {self.gender}, and my email is {self.email}.")
5.2. 创建实例并设置属性值
当你创建Person类的实例时,你需要传入所有这些属性的值:
person1 = Person("Alice", 30, "Female", "alice@example.com")
person2 = Person("Bob", 25, "Male", "bob@example.com")
# 调用greet方法
person1.greet()
person2.greet()
输出:
Hello, my name is Alice, I am 30 years old, my gender is Female, and my email is alice@example.com.
Hello, my name is Bob, I am 25 years old, my gender is Male, and my email is bob@example.com.
5.3. 在类的方法中使用其他实例属性
你可以在类的其他方法中使用这些新定义的实例属性:
def send_email(self, message):
print(f"Sending email to {self.email} with message: {message}")
# 使用send_email方法
person1.send_email("Hello, welcome to our service!")
输出:
Sending email to alice@example.com with message: Hello, welcome to our service!
5.4. 动态添加属性
除了在__init__方法中定义属性外,你还可以动态地为实例添加属性:
person1.height = 165 # 动态添加height属性
print(person1.height) # 输出: 165
5.5. 使用kwargs处理不确定数量的属性**
如果你不确定会有多少额外的属性,可以使用**kwargs(关键字参数字典)来处理:
class Person:
def __init__(self, name, age, **kwargs):
self.name = name
self.age = age
for key, value in kwargs.items():
setattr(self, key, value)
def __str__(self):
return f"{self.name}, {self.age}, {vars(self)}"
# 创建实例,传入额外的属性
person1 = Person("Alice", 30, gender="Female", email="alice@example.com")
print(person1)
输出:
Alice, 30, {'gender': 'Female', 'email': 'alice@example.com'}
5.6.使用setattr动态设置属性
setattr函数允许你动态地为对象设置属性:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# 创建实例
person = Person("Charlie", 35)
# 使用setattr设置属性
setattr(person, 'gender', 'Male')
setattr(person, 'email', 'charlie@example.com')
print(f"{person.name}, {person.age}, {getattr(person, 'gender', 'Unknown')}, {person.email}")
# 输出: Charlie, 35, Male, charlie@example.com
5.7. 使用__dict__直接操作属性字典
每个实例都有一个__dict__属性,它是一个字典,存储了所有实例属性
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# 创建实例
person = Person("David", 40)
# 直接操作__dict__
person.__dict__['gender'] = 'Male'
person.__dict__['email'] = 'david@example.com'
print(f"{person.name}, {person.age}, {person.gender}, {person.email}")
# 输出: David, 40, Male, david@example.com
总之,虽然__init__是初始化实例属性的标准位置,但你可以在类的任何地方或任何时间定义和修改实例属性。这提供了灵活性,允许你根据需要在不同的地方设置和调整对象的状态。
通过这些方法,你可以灵活地为Person类的实例定义和使用各种实例属性,以满足不同的应用场景。
6. 使用其它源文件的类或函数,变量
在Python中,如果你的程序由多个源文件组成,你可以使用import语句来使用其他源文件中的类、函数和变量。以下是一些常见的方法:
6.1. 导入整个模块
如果你有一个名为math_functions.py的文件,其中定义了一些数学相关的函数,你可以在另一个文件中导入整个模块:
# math_functions.py
def add(x, y):
return x + y
def subtract(x, y):
return x - y
# main.py
import math_functions
result = math_functions.add(5, 3)
print(result) # 输出: 8
6.2. 导入特定的函数或类
你也可以只导入你需要的函数或类:
# math_functions.py
def add(x, y):
return x + y
def subtract(x, y):
return x - y
# main.py
from math_functions import add
result = add(5, 3)
print(result) # 输出: 8
6.3. 使用别名
如果你想要为导入的模块或函数使用别名,可以使用as关键字:
# math_functions.py
def add(x, y):
return x + y
# main.py
import math_functions as mf
result = mf.add(5, 3)
print(result) # 输出: 8
from math_functions import add as add_func
result = add_func(5, 3)
print(result) # 输出: 8
6.4. 导入所有内容
你可以使用星号*来导入模块中的所有内容,但这种做法通常不推荐,因为它可能会导致命名空间污染:
# math_functions.py
def add(x, y):
return x + y
def subtract(x, y):
return x - y
# main.py
from math_functions import *
result = add(5, 3)
print(result) # 输出: 8
6.5. 相对导入
在包(目录包含__init__.py文件)中,你可以使用相对导入来导入同一包中的其他模块:
# package/
# ├── __init__.py
# ├── math_functions.py
# └── main.py
# math_functions.py
def add(x, y):
return x + y
# main.py
from .math_functions import add
result = add(5, 3)
print(result) # 输出: 8
6.6. 导入变量
如果你想要导入一个模块中的变量,可以直接使用变量名:
# config.py
API_KEY = "your_api_key"
# main.py
from config import API_KEY
print(API_KEY) # 输出: your_api_key
注意事项
确保你的文件结构和导入路径正确,Python才能找到并导入相应的模块。
使用相对导入时,确保你的脚本是作为包的一部分运行的,而不是作为独立的脚本。
尽量避免使用星号*导入所有内容,以减少命名空间污染的风险。
7.main函数
Python 是一种解释型语言,通常确实是从上到下执行代码的。但是,说“有了main函数之后就从main函数开始执行”并不完全准确。在Python中,代码的执行流程取决于几个因素,包括函数调用和入口点的定义。
-
脚本执行流程
在Python中,如果没有定义入口点(如if name == ‘main’:),代码会从上到下顺序执行。这意味着所有的函数定义、类定义和执行语句都会按照它们在脚本中出现的顺序被执行。 -
使用if name == ‘main’:
在Python中,if name == ‘main’: 是一个常用的模式,用于定义脚本的入口点。当Python文件被直接运行时,Python会设置特殊变量__name__的值为’main’。这允许你将一些代码放在这个条件块中,确保它们只在文件被直接运行时执行,而不是在文件被导入为模块时执行。
示例:
# my_script.py
def my_function():
print("This function is always executed.")
if __name__ == '__main__':
print("This part is only executed when the script is run directly.")
my_function()
- 当你直接运行my_script.py时,输出会是:
This part is only executed when the script is run directly.
This function is always executed.
- 如果你导入my_script.py到另一个Python文件中,只有my_function会被执行,if name == ‘main’:块中的代码不会被执行。
通过这些方法,你可以灵活地在Python程序中导入和使用多个源文件中的类、函数和变量。
- main函数
在Python中,并没有强制要求使用main函数。if name == ‘main’:是Python中定义程序入口点的标准方式。然而,你完全可以定义一个名为main的函数,并在if name == ‘main’:块中调用它,这只是为了组织代码的逻辑,而不是改变Python的执行流程。
示例:
# my_script.py
def main():
print("This is the main function.")
if __name__ == '__main__':
main()
总结
- Python代码通常是从上到下执行的。
- if name == ‘main’:用于定义脚本的入口点,确保某些代码只在文件被直接运行时执行。
- 你可以定义一个main函数,但这不会改变Python的执行流程,它只是提供了一种组织代码的方式。
因此,Python的执行流程并不依赖于是否存在main函数,而是依赖于代码的结构和if name == ‘main’:的使用。
8. 捕获异常的用法
在Python中,异常处理是通过使用try和except语句来实现的。以下是捕获异常的基本用法:
8.1. 基本语法:
try:
# 尝试执行的代码块,可能会引发异常
except ExceptionType as e:
# 当特定类型的异常被触发时执行的代码块
各部分解释
try:后面的代码块包含了可能会引发异常的代码。
except:指定了异常处理代码块,用于捕获并处理try块中抛出的异常。
ExceptionType:指定了要捕获的异常类型。这是Python异常层次结构中的一个类。
as e:e是一个变量,用于存储异常实例。你可以使用这个变量来获取异常的详细信息。
示例
try:
# 尝试打开一个文件
with open("non_existent_file.txt", "r") as file:
content = file.read()
except FileNotFoundError as e:
# 文件未找到时执行的代码
print(f"An error occurred: {e}")
在这个例子中,如果non_existent_file.txt文件不存在,open函数会抛出一个FileNotFoundError异常,except块会捕获这个异常并打印一条错误消息。
8.2. 捕获多个异常
你可以在一个try块后面放置多个except块,以捕获和处理不同类型的异常:
try:
# 可能会抛出多种异常的代码
value = int(input("Enter an integer: "))
result = 10 / value
except ValueError as e:
# 处理值错误异常(例如,输入不是整数)
print(f"ValueError occurred: {e}")
except ZeroDivisionError as e:
# 处理除以零异常
print(f"ZeroDivisionError occurred: {e}")
except Exception as e:
# 处理任何其他类型的异常
print(f"An unexpected error occurred: {e}")
8.3. else子句
else子句与try和except块一起使用,如果try块没有引发任何异常,则执行else块中的代码:
try:
# 可能会引发异常的代码
value = 10 / 2
except ZeroDivisionError as e:
# 处理除以零异常
print(f"Error: {e}")
else:
# 如果没有异常发生,则执行的代码
print("Division successful, result is", value)
8.4. finally子句
finally子句与try、except和else块一起使用,无论是否发生异常,finally块中的代码都会被执行:
try:
# 可能会引发异常的代码
value = 10 / 2
except ZeroDivisionError as e:
# 处理除以零异常
print(f"Error: {e}")
finally:
# 无论是否发生异常都会执行的代码
print("Execution completed.")
使用try和except语句可以帮助你控制程序中的错误处理,使程序更加健壮和用户友好。
8.5. 标准异常类
实际上,Python提供了一个完整的异常层次结构,包括许多不同的异常类,用于表示各种错误情况。
Python的标准异常类包括但不限于以下这些:
- ArithmeticError:所有算术错误(如OverflowError、ZeroDivisionError)的基类。
- AssertionError:assert语句失败时抛出。 AttributeError:对象没有某个属性时抛出。
- EOFError:到达文件末尾时抛出。 FloatingPointError:浮点运算失败时抛出。
- GeneratorExit:生成器退出时抛出。 ImportError:无法导入模块时抛出。
- IndentationError:缩进错误时抛出。 IndexError:索引超出序列范围时抛出。
- KeyError:字典中查找不存在的键时抛出。 KeyboardInterrupt:用户中断程序执行(如按Ctrl+C)时抛出。
- LookupError:所有查找错误(如IndexError、KeyError)的基类。 MemoryError:内存溢出时抛出。
- NameError:使用未定义的变量时抛出。 NotImplementedError:尚未实现的方法被调用时抛出。
- OSError:操作系统相关错误(如IOError)的基类。 OverflowError:数值溢出时抛出。
- RecursionError:递归太深时抛出。 RuntimeError:一般的运行时错误。 SyntaxError:语法错误。
- SystemError:解释器内部错误。 SystemExit:请求退出程序。 TypeError:类型不兼容时抛出。
- UnboundLocalError:访问未初始化的局部变量时抛出。 UnicodeError:Unicode相关错误。
- ValueError:传入无效的参数时抛出。 Warning:警告基类。
8.6. 自定义异常类
除了这些标准异常类之外,你还可以定义自己的异常类。自定义异常类通常继承自Exception类或其子类。这允许你创建特定于你应用程序的异常,以提供更详细的错误信息。
class MyCustomError(Exception):
"""自定义异常类"""
def __init__(self, message):
self.message = message
try:
raise MyCustomError("Something went wrong")
except MyCustomError as e:
print(e.message)
在这个例子中,MyCustomError是一个自定义异常类,它继承自Exception类,并在异常发生时提供了一个自定义的消息。
总结
Python中的异常类名并不仅限于几个固定的类,而是一个完整的层次结构,包括许多不同的异常类。此外,你还可以定义自己的异常类来满足特定的需求。通过使用和定义异常类,你可以更有效地处理和报告程序中的错误。
9.python venv使用
- 创建虚拟环境
在项目目录下运行以下命令来创建虚拟环境:
python -m venv <env_name>
<env_name> 是你给虚拟环境指定的名称,例如 myenv。
这会在当前目录下创建一个名为 <env_name> 的文件夹,里面包含了虚拟环境的 Python 解释器、标准库、pip 工具等。
2. 激活虚拟环境
创建虚拟环境后,需要激活它,这样后续的 Python 操作就会在虚拟环境中进行。
在 Windows 系统下
<env_name>\Scripts\activate
例如,如果虚拟环境名为 myenv,则运行:
myenv\Scripts\activate
- 退出虚拟环境
完成操作后,可以通过以下命令退出虚拟环境:
deactivate