先看大题:
练习题 动物园管理系统
动物园管理系统
步骤 1: 定义抽象基类 Animal 首先,我们定义一个抽象基类 Animal,它 包含抽象方法 make_sound 和普通方法 get_name。
步骤 2: 创建子类 Lion, Snake 和 Parrot 这些子类继承自 Animal 类,并实现了 make_sound 方法,展示多态和继承的概念。
步骤 3: 动物园类 Zoo Zoo 类包含一个动物列表,并提供添加动物 add_animal 和展示动物 叫声的方法 make_all_sounds。测试代码 现在,我们创建一些动物对象和一个动物园对象, 并展示它们是如何工作
#定义一个动物类
class Animal:
#定义一个构造函数
def __init__(self, name):
self.name = name
def make_sound(self):
#空语句不做任何事情
pass
def get_name(self):
return self.name
#定义一个狮子类继承动物类
class Lion(Animal):
def make_sound(self):
return "Roar!"
#定义一个蛇类继承动物类
class Snake(Animal):
def make_sound(self):
return "Hiss!"
#定义一个鹦鹉类继承动物类
class Parrot(Animal):
def make_sound(self):
return "Chirp!"
#定义一个动物园类
class Zoo:
#定义一个数组接收数据
def __init__(self):
self.animals = []
#接收animal实类
def add_animal(self, animal):
self.animals.append(animal)
#遍历接收到的动物的声音
def make_all_sounds(self):
for animal in self.animals:
print(animal.make_sound())
if __name__ == "__main__":
#类的实例化
lion = Lion("Lion")
snake = Snake("Snake")
parrot = Parrot("Parrot")
zoo = Zoo()
zoo.add_animal(lion)
zoo.add_animal(snake)
zoo.add_animal(parrot)
zoo.make_all_sounds()
print("Lion sound:", lion.make_sound())
print("Snake sound:", snake.make_sound())
print("Parrot sound:", parrot.make_sound())
练习题2: 创建和使用一个简单的包
目标:创建一个名为 geometry 的包。
在 geometry 包中, 创建两个模块:area 和 perimeter。
在 area 模块中,编写函数计算不同形状(如圆形、正 方形和矩形)的面积。
在 perimeter 模块中,编写函数计算这些形状的周长。
创建一个主 程序文件,在其中使用 geometry 包来计算不同形状的面积和周长。
#定义一个area.py的文件
geometry/area.py:
import math
def circle_area(radius):
return math.pi * radius ** 2
def square_area(side_length):
return side_length ** 2
def rectangle_area(width, height):
return width * height
#定义一个perimeter.py的文件
geometry/perimeter.py:
def circle_perimeter(radius):
return 2 * math.pi * radius
def square_perimeter(side_length):
return 4 * side_length
def rectangle_perimeter(width, height):
return 2 * (width + height)
#定义一个测试主文件
geometry/main.py:
from geometry.area import circle_area, square_area, rectangle_area
from geometry.perimeter import circle_perimeter, square_perimeter, rectangle_perimeter
def main():
circle_radius = 5
square_side_length = 4
rectangle_width = 3
rectangle_height = 4
print("Circle area:", circle_area(circle_radius))
print("Circle perimeter:", circle_perimeter(circle_radius))
print("Square area:", square_area(square_side_length))
print("Square perimeter:", square_perimeter(square_side_length))
print("Rectangle area:", rectangle_area(rectangle_width, rectangle_height))
print("Rectangle perimeter:", rectangle_perimeter(rectangle_width,rectangle_height))
if __name__ == "__main__":
main()
练习题三
用递归的方式实现二叉树的先序遍历
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
def pre_order_traversal(root):
if not root:
return
# 访问根节点
print(root.val, end=' ')
# 遍历左子树
pre_order_traversal(root.left)
# 遍历右子树
pre_order_traversal(root.right)
if __name__ == '__main__':
# 创建一个简单的二叉树
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.right.right = TreeNode(6)
# 进行先序遍历
pre_order_traversal(root)
1.python是什么
Python 是一种高级的编程语言,以其强大的功能和简洁易读的代码而闻名。以下是 Python 的一些核心特征和信息:
高级语言:Python 被设计为一种高级编程语言,这意味着它提供了较高层次的抽象,使得编程更加容易和直观。程序员可以用更少的代码行来表达复杂的想法。
解释型语言:与编译型语言(如 C 或 Java)不同,Python 是一种解释型语言。这意味着 Python 代码在运行时由解释器逐行读取和执行,而不是预先编译成机器语言。
动态类型:Python 是动态类型的,这意味着变量在声明时不需要显式指定数据类型。数据类型在运行时会自动确定。
跨平台兼容性:Python 可以在多种操作系统上运行,包括 Windows、MacOS 和 Linux,这使得它成为开发跨平台应用的理想选择。
易读性:Python 以其清晰、直观和几乎类似英语的语法而闻名,这使得代码易于理解和维护。
丰富的库和框架:Python 拥有庞大的标准库,以及丰富的第三方库和框架,覆盖了从网络编程到数据科学、机器学习、Web开发等广泛的应用领域。
广泛的应用:Python 在多个领域都有广泛的应用,包括 Web 开发、数据分析和科学计算、人工智能、自动化脚本、软件测试等。
社区支持:Python 拥有一个庞大而活跃的开发者社区,提供了大量的资源、文档、教程和支持,这对于初学者来说是一个巨大的优势。
2.3操作符
1)算术运算符:加 (+), 减 (-), 乘 (*), 除 (/), 取余 (%), 整除 (//), 指数 (**)
a = 10
b = 3
add = a + b # 加 (+)
subtract = a - b # 减 (-)
multiply = a * b # 乘 (*)
divide = a / b # 除 (/)
modulo = a % b # 取余
(%) floor_divide = a // b # 整除
(//) exponent = a ** b # 指数 (**)
2)比较运算符:等于 (==), 不等于 (!=), 大于 (>), 小于 (<), 大于等于 (>=), 小于等于 (<=)
x = 5
y = 10
equal = x == y # 等于 (==)
not_equal = x != y # 不等于
(!=) greater_than = x > y # 大于 (>)
less_than = x < y # 小于 (<)
greater_than_or_equal = x >= y # 大于等于 (>=)
less_than_or_equal = x <= y # 小于等于 (<=)
3)逻辑运算符:与 (and), 或 (or), 非 (not)
a = True
b = False
logical_and = a and b # 与
(and) logical_or = a or b # 或 (or)
logical_not = not a # 非 (not)
4)赋值运算符:赋值 (=), 加赋值 (+=), 减赋值 (-=), 乘赋值 (*=), 除赋值 (/=), 等等
x = 10
x += 3 # 加赋值 (+=)
x -= 2 # 减赋值 (-=)
x *= 2 # 乘赋值 (*=)
x /= 4 # 除赋值 (/=)
2.5注释 斐波那契数列
使用 # 符号来添加注释,解释代码的功能或目的。
# 这是一个注释 print("Hello, World!")
"""
这是一个多行注释的示例。 你可以在这里写很多行文字,
而 Python 解释器会忽略它们。
"""
3.1字符串链接重复 切片
1)连接(Concatenation)
使用+将字符串连接在一起。
str1 = "Hello" str2 = "World" combined = str1 + " " + str2 # "Hello World"
2)重复(Repetition):
使用*重复字符串。
repeat_str = "Python!" * 3 # "Python!Python!Python!"
3)索引(Indexing):
使用索引访问特定位置的字符。
char = "Hello"[1] # 'e'
4)切片(Slicing):
使用切片来获取字符串的子串。
substring = "Hello World"[1:5] # "ello"
3.4 2.2字典
字典(dict)是一种可变的容器,可以存储任意类型对象,其中每个元素都是一个键值对。
定义和用法
person = {"name": "Alice", "age": 25} capitals = {"France": "Paris", "Italy": "Rome"}
特点
1. 键必须是不可变类型,如字符串或元组
# 使用字符串作为键
my_dict = { "name": "Alice",
"age": 30,
"email": "[email protected]"
} # 使用元组作为键
coordinates = {(0, 0): "原点", (1, 1): "点(1,1)"}
# 尝试使用可变类型(如列表)作为键将引发错误
try: invalid_dict = {[1, 2, 3]: "List as a key"}
except TypeError as e:
print("Error:", e)
PS:可以作为Key的类型:
字符串(String):
例子:"name", "id", "email"
整数(Integer):
例子:1, 100, -20
浮点数(Float):
注意:尽管可以使用,但由于浮点数精度的问题,通常不建议将其作为键。
例子:3.14, 0.001, -5.76
元组(Tuple):
条件:元组中的所有元素也必须是不可变类型。
例子:(1, 2, 3), ("a", "b", "c")
布尔值(Boolean):
例子:True, False
冻结集合(Frozenset):
条件:类似于集合,但是不可变。
例子:frozenset([1, 2, 3]), frozenset(["apple", "banana"])
字典是可变的,存储键值对的无序集合。
# 创建字典
my_dict = {"name": "Alice", "age": 25, "city": "New York"}
# 添加或修改元素
my_dict["country"] = "USA" # 添加新键值对
my_dict["age"] = 26 # 修改现有键的值
# 访问
name = my_dict.get("name") # 安全地访问元素
age = my_dict.pop("age") # 删除键值对并返回值
# 遍历字典
or key, value in my_dict.items():
print(key, value)
# 删除元素
del my_dict["city"] # 删除键值对
# 注意:此时 "age" 键已经被 pop 方法删除,再次调用 pop 将引发 KeyError
# 若要避免错误,可以使用 pop 方法的第二个参数,提供默认返回值
# 这样,如果键不存在,将返回默认值而不是引发异常
age_removed = my_dict.pop("age", None)
# 打印结果
print(f"Name: {name}")
print(f"Age: {age} (removed)")
print(f"Age removed again: {age_removed} (default None if not found)")
运算符 |
描述 |
支持的容器类型 |
---|---|---|
+ |
合并 |
字符串、列表、元组 |
* |
复制 |
字符串、列表、元组 |
in |
元素是否存在 |
字符串、列表、元组、字典 |
not in |
元素是否不存在 |
字符串、列表、元组、字典 |
# 字符串操作示例
str1 = "Hello"
str2 = "World"
str_concat = str1 + " " + str2# 合并
str_repeat = str1 * 3 # 复制
str_in = "H" in str1 # 元素是否存在
str_not_in = "Z" not in str1 # 元素是否不存在
# 列表操作示例
list1 = [1, 2, 3]
list2 = [4, 5, 6]
list_concat = list1 + list2 # 合并
list_repeat = list1 * 2 # 复制
list_in = 1 in list1 # 元素是否存在
list_not_in = 7 not in list1 # 元素是否不存在
# 元组操作示例
tuple1 = (1, 2, 3)
tuple2 = (4, 5, 6) t
uple_concat = tuple1 + tuple2 # 合并
tuple_repeat = tuple1 * 2 # 复制
tuple_in = 1 in tuple1 # 元素是否存在
tuple_not_in = 7 not in tuple1 # 元素是否不存在
# 字典操作示例(只适用于 in 和 not in 运算符)
dict1 = {"name": "Alice", "age": 25}
dict_in = "name" in dict1 # 元素(键)是否存在
dict_not_in = "salary" not in dict1 # 元素(键)是否不存在
# 打印所有结果
print(f"String Concatenation: {str_concat}")
print(f"String Repetition: {str_repeat}")
print(f"String In: {str_in}, String Not In: {str_not_in}")
(f"List Concatenation: {list_concat}")
print(f"List Repetition: {list_repeat}")
print(f"List In: {list_in}, List Not In: {list_not_in}")
print(f"Tuple Concatenation: {tuple_concat}")
print(f"Tuple Repetition: {tuple_repeat}")
print(f"Tuple In: {tuple_in}, Tuple Not In: {tuple_not_in}")
print(f"Dictionary In: {dict_in}, Dictionary Not In: {dict_not_in}")
1.3作用域和命名空间1 2 3 4(背)
局部变量:在函数内部定义的变量是局部的,它们只在函数内部可见。
全局变量:在函数外定义的变量是全局的,它们在程序的任何地方都可见。
作用域规则:Python 使用 LEGB(Local, Enclosing, Global, Built-in)规则来解析变量名。
变量的可见性和生命周期取决于它们被定义的地方,这就是所谓的作用域。Python 的作用域规则遵循 LEGB 规则,这个规则决定了在任何给定的点在你的代码中使用变量时,Python 如何查找该变量的值。LEGB 代表 Local, Enclosing, Global, Built-in:
局部作用域指的是在函数内部定义的变量。
这些变量只能在其定义的函数内部访问。
def my_function():
local_var = 10 # 局部变量
print(local_var)
my_function()
# print(local_var) # 这将引发错误,因为 local_var 在函数外部不可见
封闭作用域涉及嵌套函数,即一个函数包裹着另一个函数。
在外层函数中定义的变量对内层函数来说是可见的,但不适用于相反的情况。
def outer_function():
enclosing_var = "I'm outside the nested function."
def inner_function():
print(enclosing_var) # 访问封闭作用域中的变量
inner_function()
outer_function()
全局变量是在函数外部定义的,它们在整个代码文件中都是可见的。
如果需要在函数内修改全局变量,需要使用 global 关键字。
# 定义一个全局变量
global_var = 10 def update_var():
global_var = 20
print(f"Inside function update var: global_var = {global_var}")
def update_global_var():
# 在函数内部声明要使用的全局变量
global global_va
r # 修改全局变量的值
global_var = 20
print(f"Inside function use global update var: global_var = {global_var}")
print(f"Before update_var call: global_var = {global_var}") update_var()
print(f"After update_var call: global_var = {global_var}")
print(f"Before update_global_var call: global_var = {global_var}") update_global_var() print(f"After update_global_var call: global_var = {global_var}")
Python 自带了一些内置函数和变量,它们在任何地方都是可访问的。
这些内置函数包括 print(), len() 等,不建议覆盖这些内置函数。
print(len("hello")) # 使用内置函数 len()
当你在代码中引用一个变量时,Python 会按照 LEGB 的顺序搜索:
首先查看 Local 层,看变量是否在函数内部定义。
然后是 Enclosing 层,检查任何外层函数是否定义了变量。
接着是 Global 层,搜索代码文件的顶层。
最后是 Built-in 层,检查变量名是否是 Python 的内置名称。
2.3 类方法 静态方法(背)
类方法
需要用装饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数。
当方法中 需要使用类对象 (如访问私有类属性等)时,定义类方法
类方法一般和类属性配合使用
class Dog:
__tooth = 10
@classmethod
def get_tooth(cls):
return cls.__tooth
......
print(Dog.get_tooth())
print(my_dog.get_tooth())
静态方法
需要通过装饰器@staticmethod来进行修饰,静态方法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)。
静态方法 也能够通过 实例对象 和 类对象 去访问。
当方法中 既不需要使用实例对象(如实例对象,实例属性),也不需要使用类对象 (如类属性、类方法、创建实例等)时,定义静态方法
取消不需要的参数传递,有利于 减少不必要的内存占用和性能消耗
class Dog:
......
@staticmethod
def info_print():
print('这是一个狗类,用于创建狗实例....')
.....
# 静态方法既可以使用对象访问又可以使用类访问
my_dog.info_print()
Dog.info_print()
定义私有属性
在Python中,以双下划线 __ 开始的属性或方法被视为私有的。
私有属性不能从类的外部直接访问,只能在类的内部使用。
私有属性的目的是为了封装和隐藏类的内部实现细节。
尽管Python的私有化是通过名称改写(Name Mangling)实现的(例如 __max_price 会被改写为 _Computer__max_price),这并不是强制性的,仍可以通过特定的语法访问它们,但这种做法不被推荐,因为它违反了封装原则。
2.5抽象基类
在 Python 中,与传统意义上的“接口”(如在 Java 或 C# 中所见)不同,没有专门的接口(Interface)类或关键字。然而,Python 支持接口编程的概念,通常是通过抽象基类(Abstract Base Classes, ABCs)来实现的。
这些类可以包含一个或多个抽象方法或属性,这些方法或属性需要在子类中实现。抽象基类本身不能被实例化。在这方面,抽象基类的作用类似于传统的接口,它们定义了一个接口契约,该契约必须由任何非抽象的子类实现。
from abc import ABC, abstractmethod
class MyInterface(ABC):
@abstractmethod
def do_something(self):
pass
@abstractmethod
def do_something_else(self):
pass
class ConcreteClass(MyInterface):
def do_something(self):
return "Doing something!"
def do_something_else(self):
return "Doing something else!"
# my_interface = MyInterface() # 这会引发错误,因为不能实例化抽象类
concrete = ConcreteClass()
print(concrete.do_something())
在这个例子中,MyInterface 是一个抽象基类,它定义了两个抽象方法:do_something 和 do_something_else。ConcreteClass 继承自 MyInterface 并实现了这些方法。尝试直接实例化 MyInterface 会引发错误,因为它是抽象的