day1:
# 单行注释,空格隔开
‘’‘ 多行注释 ’‘’
type的一个小知识点:在Python中,type()
函数用于获取任何对象的类型,包括内置的数据类型如字符串(str
)、整数(int
)、浮点数(float
)等。type()
函数返回的是一个type
对象,而不是字符串。不过,当你将type()
函数的返回值转换为字符串时,比如使用str()
函数或者在打印时,显示的结果将是类型的名称,这看起来像是一个字符串。
强制转换和C类似:int(a),str(a),float(a);但是强制转换只是得到了一个结果,没有对变量本身进行处理,因此若对于变量本身进行复制处理还需要加上类似a=str(a);
标识符的命名: 数字不可以开头,支持中文,其他和c同理
运算符:
同理可得赋值运算符:
不同于c,python字符串有三种定义方法:
转义字符在python中也是有用的
字符串拼接:用”+“来拼接两个字符串字面量或者字符串变量。(只能拼接字面量!)
字符串格式化:有多种方法,但是现在最常用的是-f格式化方法如下:
如何使用f-字符串
要创建一个f-字符串,只需在字符串的开头加上字母f或F,
然后在花括号{}中写入Python表达式。当字符串被解释执行时,
花括号内的表达式会被求值,并将其结果插入到字符串中的相应位置。
这里是一些使用f-字符串的例子:
python
Copy code
name = "Alice"
age = 30
print(f"The person's name is {name} and their age is {age}.")
f-字符串的特点
简洁性:f-字符串提供了一种非常直接的方式来嵌入表达式的值到字符串中,减少了代码的冗余,提高了可读性。
表达式内嵌:你可以在f-字符串的花括号中放置任何有效的Python表达式,包括变量、算术表达式、函数调用等。
高性能:与其他字符串格式化方法相比,f-字符串在性能上通常更优,因为它们在运行时直接被解释和执行。
格式化选项:f-字符串支持复杂的表达式和格式化选项,如设置浮点数的精度、进行值的格式化等。
字符串的精度控制:若使用”%“则和c相似,若使用-f方法则如下
num = 3.14159
print(f"{num:.2f}")
# 输出:3.14
同时我们也不能摒弃利用%占位的这种方法,因为它和c是相通的。
数据输入(键盘):使用input即可。input(promote)中promote会在输入前显示。
但是input输入的只是字符串,因此想获得输入的数字时必须显示的进行类型转换
布尔类型:在python中,布尔类型是可以输出为True和False的。
if的用法:
while循环的用法 :和c基本一样,只是需要进行严格的格式控制。
while i<1:
print("let's go warriors)
i=i+1
for循环:和C有非常大的不同是一种遍历循环
# 定义一个列表
fruits = ['apple', 'banana', 'cherry']
# 使用for循环遍历列表
for fruit in fruits:
print(fruit)
# 定义一个字符串
name = "curry"
# 使用for循环遍历字符串
for letter in name:
print(letter)
range语句:
for i in range(5): # 默认从0开始,到5(不包括5)
print(i)
for i in range(2, 6): # 从2开始到6(不包括6)
print(i)
for i in range(0, 10, 2): # 从0开始到10(不包括10),步长为2
print(i)
for循环的变量作用域:for循环内部的变量在规范上不能在外部访问
print换行:
print("Hello, world!", end='') # 不会在输出后添加换行符
print(" Still on the same line.")
continue和break:在循环中的作用与c完全一样
函数的定义:python中的函数格式如下
def 函数名(参数列表):
"""
函数文档字符串(可选)
"""
# 函数体
# 执行操作
return 返回值
值得注意的是,在Python中,函数的声明和定义是一体化的,这与C语言等静态类型语言的分离式声明和定义机制不同。在Python中,当你定义一个函数,你实际上同时完成了声明和定义两个步骤。这是因为Python是一种动态类型语言,它不需要事先声明变量或函数的类型。
函数的参数与输出:不同于C,python中的函数参数和输出不需要严格的定义(就是可不需要),并且pyhon的函数是不分类型的。
函数返回的none:python中如果不适用return函数返回的就是<class 'NoneType'>,和在定义中显式的写return none效果是一样的。
函数的说明文档:
在Python中,函数的说明文档(也称为文档字符串或docstrings)是一种重要的文档工具,用于解释函数的目的和如何使用它。文档字符串紧跟在函数定义的下一行,使用三引号("""
)包围。这些字符串可以通过函数的__doc__
属性访问,并且可以被各种文档生成工具,如Sphinx,自动提取。
编写良好的文档字符串
良好的文档字符串应该简明扼要地描述函数的功能,并且详细说明函数的参数、返回值、引发的异常以及其他行为。按照PEP 257(Python的docstring约定)和Google Python风格指南,这里是一些建议:
-
简短描述:首行应该是一个简洁的函数功能概述。
-
参数(Args):列出每个参数的名字,后面跟一个空格、冒号、再跟一个空格,然后是参数的类型,以及一个简短的描述。
-
返回值(Returns):指明返回值的类型和一个描述。如果函数没有明确返回值(即返回
None
),这部分可以省略。 -
异常(Raises):列出函数可能引发的所有异常。
-
其他部分:如“注意”(Notes)、“示例”(Examples)等,可以根据需要添加。
下面是一个包含文档字符串的函数示例,遵循了上述的文档字符串规范:
def add(a, b):
"""
Calculate the sum of two numbers.
:Args:
a (int): The first number.
b (int): The second number.
:Returns:
int: The sum of `a` and `b`.
"""
return a + b
嵌套调用:在python中,函数嵌套调用与其自身定义的顺序无关。
局部变量与全局变量:和C相似的,但是利用global关键字可以在函数内定义全局变量。
x = "global"
def test():
global x
x = "modified by test"
test()
print(x) # 输出:modified by test
列表(list):
列表是支持嵌套的。
方法:方法是与类的实例相关联的函数。换句话说,所有方法都是函数,但不是所有函数都是方法。
# 定义一个函数
def my_function():
print("This is a function.")
# 定义一个类和一个方法
class MyClass:
def my_method(self):
print("This is a method of MyClass.")
# 调用函数
my_function()
# 创建类的实例并调用方法
my_object = MyClass()
my_object.my_method()
必须要先创建类的实例再调用方法,但是python内置的方法可以直接调用而不需要创建实例。
列表的方法:列表自身内置了多种方法
my_list = [3, 1, 4, 1, 5, 9, 2]
my_list.append(6) # 添加元素6到列表末尾
my_list.extend([5, 3, 5]) # 扩展列表,添加多个元素
my_list.remove(1) # 删除列表中第一个出现的元素
item = my_list.pop(n) # 删除并返回列表的下标为n的元素
my_list.sort() # 对列表进行排序
my_list.reverse() # 反转列表
copy_of_my_list = my_list.copy() # 复制列表
my_list.clear() # 彻底清空列表
my_list.index(x[, start[, end]]): #返回列表中第一个值为x的元素的索引。如果没有这样的元素会抛出一个ValueError。可选参数start和end用于指定搜索的起始和结束位置。
my_list.count(x): #返回x在列表中出现的次数。
列表的遍历:
元组:元组可以看作只读的,不可修改的列表。
warriors = ("curry", "klay", "green", "durant", 'ig')
字符串的多种方法:
# 创建一个示例字符串
sample_string = " Python programming is fun! "
# 修改字符串
print(sample_string.capitalize()) # 将第一个字符转换为大写
print(sample_string.lower()) # 转换为小写
print(sample_string.upper()) # 转换为大写
print(sample_string.swapcase()) # 大小写互换
print(sample_string.title()) # 每个单词的首字母大写
# 文本对齐
print(sample_string.center(40, '*')) # 居中对齐,使用*填充
print(sample_string.ljust(40, '-')) # 左对齐,使用-填充
print(sample_string.rjust(40, '-')) # 右对齐,使用-填充
print("42".zfill(5)) # 数字字符串左侧填充0
# 去除空白
print(sample_string.strip()) # 删除前后空白符
print(sample_string.lstrip()) # 删除左侧空白符
print(sample_string.rstrip()) # 删除右侧空白符
# 搜索和替换
print(sample_string.find('fun')) # 查找子字符串,返回第一个匹配的索引
print(sample_string.replace('fun', 'awesome')) # 替换子字符串
# 分割和组合
words = sample_string.split() # 默认以空白符分割字符串
print(words)
print(','.join(words)) # 使用逗号将字符串列表组合成一个字符串
# 字符串判断
print(sample_string.startswith(" Python")) # 检查字符串是否以" Python"开始
print(sample_string.endswith("fun! ")) # 检查字符串是否以"fun! "结束
print(sample_string.isnumeric()) # 检查字符串是否只包含数字
# 字符串分片
print(sample_string[2:7]) # 获取子字符串,从索引2到索引7
# 字符串倒序
original_string = "Hello, world!"
reversed_string = original_string[::-1]
print(reversed_string)
'''
在Python中使用切片操作时,语法是 [start:stop:step]。
start 表示切片开始的位置,stop 表示切片结束的位置(但不包括该位置的元素),
而 step 表示步长,即每次移动的元素数量。当步长是负数时,表示反向选择元素。
'''
序列:在Python中,序列(Sequence)是一种基本的数据结构,它表示一个元素的有序集合。序列允许包含重复元素,并且每个元素都有一个唯一的索引,索引从0开始。Python内置了多种序列类型,包括列表(List)、元组(Tuple)和字符串(String)等。这些序列类型共享一组通用的操作,比如索引、切片、迭代、成员检查、长度查询等。
序列的共通特性主要包括:
- 索引(Indexing):可以通过索引访问序列中的特定元素。
-
my_list = [1, 2, 3, 4] print(my_list[2]) # 输出: 3
- 切片(Slicing):可以获取序列的一部分。
-
my_string = "Hello, world!" print(my_string[1:5]) # 输出: ello
- 迭代(Iteration):可以遍历序列中的每个元素。
-
for item in my_list: print(item)
- 成员检查:可以检查一个元素是否属于序列。
-
if "world" in my_string: print("Found 'world' in my_string")
- 长度查询:可以获取序列包含的元素数量。
-
print(len(my_list)) # 输出: 4
集合: 在Python中,集合(Set)是一个无序的数据结构,用于存储唯一的元素。集合类似于数学中的集合概念,提供了用于执行集合运算的方法,如并集、交集、差集和对称差分等。集合主要用于成员资格测试、去除重复项以及计算上述集合操作。
集合中的元素必须是不可变(hashable)的,因此不能包含列表、字典或其他集合作为其元素。
集合是无序的,这意味着集合中的元素没有固定的顺序。
集合会自动去重。
基础的定义如下
# 使用大括号创建集合
my_set = {1, 2, 3}
# 使用set()函数创建集合
my_set2 = set([2, 3, 4])
# 创建空集合
empty_set = set()
一些集合的方法
# 创建集合
my_set = {1, 2, 3}
print(my_set) # 输出: {1, 2, 3}
# 添加元素
my_set.add(4)
print(my_set) # 输出: {1, 2, 3, 4}
# 更新集合,添加多个元素
my_set.update([5, 6])
print(my_set) # 输出: {1, 2, 3, 4, 5, 6}
# 删除元素,如果元素不存在,抛出KeyError
my_set.remove(6)
print(my_set) # 输出: {1, 2, 3, 4, 5}
# 删除元素,如果元素不存在,不会抛出错误
my_set.discard(5)
print(my_set) # 输出: {1, 2, 3, 4}
# 随机删除一个元素并返回它
removed_element = my_set.pop()
print(removed_element)
print(my_set)
# 清空集合
my_set.clear()
print(my_set) # 输出: set()
# 集合的复制
my_set = {1, 2, 3, 4}
new_set = my_set.copy()
print(new_set) # 输出: {1, 2, 3, 4}
# 集合的并集
set_a = {1, 2, 3}
set_b = {3, 4, 5}
union_set = set_a.union(set_b)
print(union_set) # 输出: {1, 2, 3, 4, 5}
# 集合的交集
intersection_set = set_a.intersection(set_b)
print(intersection_set) # 输出: {3}
# 集合的差集
difference_set = set_a.difference(set_b)
print(difference_set) # 输出: {1, 2}
# 集合的对称差集(存在于set_a或set_b中,但不会同时存在于二者中)
symmetric_difference_set = set_a.symmetric_difference(set_b)
print(symmetric_difference_set) # 输出: {1, 2, 4, 5}
# 判断是否是子集
is_subset = set_a.issubset({1, 2, 3, 4})
print(is_subset) # 输出: True
# 判断是否是超集
is_superset = set_a.issuperset({1, 2})
print(is_superset) # 输出: True
# 判断两个集合是否没有交集
no_intersection = set_a.isdisjoint({5, 6, 7})
print(no_intersection) # 输出: True
字典:
在Python中,字典(Dictionary)是一种内置的数据结构,用于存储键值对(key-value pairs)的无序集合。字典允许你通过唯一的键来存储、检索和修改值。这种数据结构在其他编程语言中可能被称为哈希表(Hash tables)或关联数组(Associative arrays)。
字典的基本特性
- 无序性:字典中的元素没有特定的顺序。在Python 3.7及以后的版本中,字典会按照插入的顺序保持元素的顺序,但这是实现的一个细节,并不改变字典本质上的无序性。
- 可变性:字典是可变的,你可以随时添加、删除或修改键值对(key+value)的组合。
- 键的唯一性:每个键在字典中必须是唯一的。如果你尝试使用一个已经存在的键来添加新的键值对,原有的值会被新的值覆盖。
- 键的不可变性:字典的键必须是不可变类型,比如数字、字符串或元组。
字典是可以嵌套定义的
# 创建一个嵌套字典,存储两个人的个人信息
people = {
"person1": {
"name": "John",
"age": 30,
"email": "john@example.com"
},
"person2": {
"name": "Alice",
"age": 25,
"email": "alice@example.com"
}
}
# 访问嵌套字典
print(people["person1"]["name"]) # 输出: John
print(people["person2"]["age"]) # 输出: 25
访问和修改字典:
# 访问字典中的值
print(my_dict['name']) # 输出: John
# 添加或修改键值对
my_dict['email'] = 'john@example.com'
my_dict['age'] = 31
# 删除键值对
del my_dict['age']
字典的多种方法:
# 获取所有键
keys = my_dict.keys()
# 获取所有值
values = my_dict.values()
# 获取所有键值对
items = my_dict.items()
# 使用get方法访问键的值,如果键不存在,可以返回默认值
email = my_dict.get('email', 'Not provided')
# 删除键值对并返回其值
email = my_dict.pop('email')
# 清空字典
my_dict.clear()
字典遍历:
for key, value in my_dict.items():
print(f"{key}: {value}")
嵌套字典输出的例子:
for person_id, personal_info in people.items():
print(f"this is the information of {person_id}")
for key in personal_info:
print(f"{key} : {personal_info[key]}")
数据容器的简单分类:
数据类型的通用操作:
函数返回多个返回值
def return():
return 1,2
x, y =return()
python中的三种参数:
1.位置参数 (Positional Arguments): 这是最常见的参数类型,调用函数时根据函数定义中参数的位置来传递值。
2.关键字参数 (Keyword Arguments): 调用函数时,通过“键=值”的形式指定,使得参数的顺序不再重要,代码的可读性也更强。
def user_info(name, age, gender):
print(f"his name is{name},age is {age},gender is {gender}")
user_info(age=18, name="curry", gender="man")
3.默认参数 (Default Arguments): 在定义函数时,可以为参数提供默认值。如果调用函数时没有传递该参数,则使用默认值。
def greet(name, message="Hello"):
print(f"{message}, {name}!")
greet("Alice") # 使用默认的问候语
greet("Bob", "Goodbye") # 使用自定义的问候语
4.可变位置参数 (Arbitrary Positional Arguments): 使用*args
形式定义,可以接受任意数量的位置参数。这些参数在函数内部作为元组处理。
使用*args
表示可变位置参数。在函数定义中,*args
会将传递给函数的所有位置参数收集到一个元组中。这意味着,即使你在调用函数时传递了多个位置参数,函数内部也能通过args
访问它们。
def print_args(*args):
for arg in args:
print(arg)
print_args(1, 2, 3, 'a', 'b')
5.可变关键字参数 (Arbitrary Keyword Arguments): 使用**kwargs
形式定义,可以接受任意数量的关键字参数。这些参数在函数内部作为字典处理。
使用**kwargs
表示可变关键字参数。在函数定义中,**kwargs
会将传递给函数的所有关键字参数收集到一个字典中。这意味着,即使你在调用函数时传递了多个关键字参数,函数内部也能通过kwargs
以键值对的形式访问它们。
def print_kwargs(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_kwargs(a=1, b=2, c=3)
4,5是可以混合传入的
def print_args_and_kwargs(*args, **kwargs):
for arg in args:
print(arg)
for key, value in kwargs.items():
print(f"{key}: {value}")
print_args_and_kwargs(1, 2, 'a', x=100, y=200)
在这个例子中,print_args_and_kwargs
函数同时接受任意数量的位置参数和关键字参数。位置参数通过args
元组访问,关键字参数通过kwargs
字典访问。
函数的传递:在Python中,函数是一等公民(first-class citizens),这意味着它们可以像任何其他对象一样被传递和操作。这包括将函数作为参数传递给另一个函数。这种能力是高阶函数(higher-order function)的一个关键特征,使得Python编程更加灵活和强大。
当你将一个函数作为参数传递给另一个函数时,你实际上是在传递那个函数的引用。接收该函数的函数可以执行传递给它的函数。
传入函数就是计算逻辑的传入,传入参数就是数据的传入
def greet(name):
return f"Hello, {name}!"
def farewell(name):
return f"Goodbye, {name}."
def operate_on_name(func, name):
greeting = func(name)
print(greeting)
operate_on_name(greet, "Alice")
operate_on_name(farewell, "Bob")
lambda函数(匿名函数):
lambda arguments: expression
lambda
函数通常用在需要简单函数的场景中,特别是作为参数传递给高阶函数(如map()
, filter()
, sorted()
等)时。由于lambda
函数的定义非常简短,它们可以直接嵌入到调用中,无需额外定义函数。
numbers = [1, 2, 3, 4, 5]
doubled = list(map(lambda x: x * 2, numbers))
print(doubled)
python的文件操作:
打开文件:使用open()
函数打开文件。这个函数返回一个文件对象,用于后续的读取操作。
open("txt",'r',encoding="utf-8")
如果文件不是特别大,可以一次性读取整个文件的内容到一个字符串中。
这里使用的是read方法,因此必须在定义了f(已经传入了文件的变量)后进行方法的使用。
# 打开文件并读取内容
with open('example.txt', 'r') as f:
content = f.read()
print(content)
在这个例子中,with open('example.txt', 'r') as f:
这行代码使用with
语句来打开文件,确保文件在使用后会被正确关闭。'r'
参数表示以读取模式打开文件。f.read()
调用读取文件的全部内容,并将其存储在变量content
中,随后通过print(content)
打印出来。
读取几个字节。
f.read(10) # 读取十个字节
不过再调用read(10)会从第十一个字节处开始读。
readline()
每次读取文件的一行。
with open('example.txt', 'r') as f:
line = f.readline()
while line:
print(line, end='') # 打印一行内容
line = f.readline()
readlines()
一次性读取所有行作为一个列表,每个元素是文件中的一行。
with open('example.txt', 'r') as f:
lines = f.readlines()
for line in lines:
print(line, end='')
每一行按顺序封装到一个列表里。
Python的文件对象是可迭代的,最简洁的逐行读取文件的方法是直接迭代文件对象。
with open('example.txt', 'r') as f:
for line in f:
print(line, end='')
文件关闭:
f.colse()
文件的写入:
在Python中,write
方法用于向文件写入内容,而flush
方法用于确保所有缓冲的输出都被写入底层存储设备。这两个方法在进行文件操作时经常一起使用,特别是在需要即时看到文件更新的场景中。
write方法
write
方法是文件对象的一个方法,用于将字符串写入文件。当你在写入模式('w'
)、追加模式('a'
)或更新模式('+'
)下打开文件时,都可以使用这个方法。write
方法不会自动在字符串末尾添加换行符(\n
),因此如果需要换行,必须手动添加。
‘w'和’a'模式下文件不存在会被人为创建。
with open('example.txt', 'w') as file:
file.write('Hello, world!\n')
在写入模式('w'
)下打开已存在的文件会导致原有内容被覆盖。如果需要保留原有内容,请使用追加模式('a'
)。
flush方法(不一定必须显式调用)
在写文件时,出于性能考虑,Python(以及大多数操作系统)会使用缓冲区。这意味着当你调用write
方法时,数据可能不会立即写入磁盘,而是首先被存储在内存中的一个临时区域。只有当缓冲区满了或者文件被关闭时,这些数据才会被实际写入磁盘。flush
方法可以用来手动清空这个缓冲区,即强制将缓冲区内的数据立即写入文件,而不必等到自动刷新。
with open('example.txt', 'w') as file:
file.write('Some data')
file.flush() # 确保'Some data'立即被写入磁盘
虽然flush
方法可以确保数据的即时写入,但频繁调用flush
可能会对性能产生负面影响,因为它减少了操作系统进行批量数据写入的机会。因此,在不需要即时反馈的场景下,应避免过度使用flush
方法。
当使用with
语句进行文件操作时,退出with
代码块的时候,Python会自动调用文件对象的close()
方法来关闭文件。这确保了无论文件操作过程中是否发生异常,文件都能被正确关闭。
在关闭文件时,close()
方法会自动确保所有缓冲区内的数据被刷新(flush)到磁盘上,这意味着在with
语句结束时,不仅文件会被关闭,所有未写入磁盘的数据也会被自动写入,无需手动调用flush()
方法。
因此,对于一般的文件写入操作,只要使用with
语句正确管理文件资源,就不需要显式地调用flush()
方法,因为close()
方法(由with
语句自动调用)已经隐含了刷新缓冲区的功能。这样可以简化代码,同时保持了代码的健壮性和安全性。
python中的error:
捕获异常:
在Python中,异常处理是通过try
...except
语句来实现的。这允许程序在遇到错误时优雅地恢复,而不是完全中断执行。以下是如何使用try
...except
语句捕获和处理异常的基本方法:
基本结构
try:
# 尝试执行的代码块
# 可能会引发异常的操作
except SomeException:
# 如果在try部分引发了SomeException,就执行这个代码块
# 异常处理代码
捕获特定异常
你可以指定一个或多个特定的异常类型来捕获:
try:
result = 10 / 0
except ZeroDivisionError:
print("除以零错误!")
try:
# 可能引发多种类型异常的操作
except (ZeroDivisionError, ValueError) as e:
print(f"发生了错误:{e}")
else
和finally
子句
else
子句:如果try
块没有引发异常,则执行else
块的代码。finally
子句:无论是否发生异常,finally
块的代码总是执行,常用于执行清理工作,如关闭文件。try: # 尝试执行的代码 except SomeException: # 处理异常 else: # 如果没有异常发生,则执行这块代码 finally: # 无论是否发生异常,都执行这块代码
实例:综合应用
try: f = open("不存在的文件.txt") content = f.read() f.close() except FileNotFoundError: print("文件未找到!") except Exception as e: print(f"发生了其他错误:{e}") else: print("文件读取成功!") finally: print("执行结束,不管是否发生了异常。")
异常的传递性:
模块的导入:
import是必写的,通过点就可以使用模块中的任何对象。
导入模块中的特定内容
如果你只需要从模块中导入特定的函数或变量,可以使用from ... import ...
语句:
from mymodule import greeting
greeting("World")
输入import *就是导入模块中的所有方法
重命名模块
你可以在导入模块时使用as
关键字为模块指定一个别名:
import mymodule as mm
mm.greeting("Python")
模块的__name__
属性
每个模块都有一个内置属性__name__
,当模块被直接运行时,__name__
的值为"__main__"
;如果模块被导入,__name__
的值则为模块的名称。这允许模块根据它们是被导入还是被直接运行来改变它们的行为:
# mymodule.py
def greeting(name):
print(f"Hello, {name}")
if __name__ == "__main__":
greeting("Python")
如果不这样写会导致from语句在主模块运行的时候就已经调用了被调用模块里的函数,这个属性方便了我们对于自己写的模块进行调试。
__all__变量:
python包:
创建包
创建一个包涉及创建一个目录,然后在该目录中添加模块文件和一个__init__.py
文件。例如,创建一个名为mypackage
的包,它包含两个模块:module1.py
和module2.py
。目录结构将如下所示:
mypackage/
__init__.py
module1.py
module2.py
导入包中的模块
你可以使用import
语句导入包中的模块。使用点(.
)来指定包和模块的路径。例如,导入上面示例中的模块:
import mypackage.module1
import mypackage.module2
mypackage.module1.some_function()
mypackage.module2.another_function()
或者使用from ... import ...
语法导入特定的函数:
from mypackage.module1 import some_function
from mypackage.module2 import another_function
some_function()
another_function()
python的可视化
json语言:JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。
import json
data = {"name": "John", "age": 30, "city": "New York"}
json_str = json.dumps(data)
print(json_str) # 输出JSON字符串
使用pyecharts实现图表构建 :过多不再赘述
对象:
在Python中,类是面向对象编程(OOP)的一个核心概念。类提供了一种组织和封装数据及功能(方法)的方式。通过类,你可以创建对象(类的实例),每个对象可以拥有自己的属性(变量)和方法(函数)。
定义类
类是通过关键字class
定义的,后跟类名和冒号。类名通常使用大驼峰命名法(CamelCase)。
class MyClass:
pass
方法就是类内部的函数
在面向对象编程(OOP)中,类和对象是两个基本概念,它们之间有着明确的区别:
类(Class)
- 定义:类是一个用于创建对象的模板或蓝图。它定义了一组属性(称为成员变量)和方法(称为成员函数或成员方法),这些属性和方法将被它创建的对象共有。
- 抽象性:类是抽象的,它不占用计算机的内存资源。类仅仅定义了对象的结构和行为,但不表示任何具体的数据。
- 设计层面:在软件开发的设计阶段,类用于定义和规划如何构建具体的对象,包括对象将拥有的数据以及能够执行的操作。
对象(Object)
- 定义:对象是根据类创建的实例。如果说类是蓝图,那么对象就是根据这个蓝图构建的房子。每个对象都拥有类中定义的属性和方法。
- 具体性:对象是具体的,每个对象都占用一定的内存空间,并包含实际的数据值。同一个类的不同对象在内存中有各自独立的存储位置。
- 运行时实体:对象的创建和使用是在程序运行时发生的。通过类创建对象的过程称为实例化。每个对象都有自己的属性状态,这些状态可以独立于其他对象进行更改。
举例说明
假设有一个类叫做Car
,它定义了汽车的一般特性,比如品牌(brand
)、颜色(color
)和驱动(drive
)方法。这个类本身并不代表任何具体的汽车。
class Car:
def __init__(self, brand, color):
self.brand = brand
self.color = color
def drive(self):
print("This car is driving.")
当你根据Car
类创建具体的对象时,每个对象都代表了一个具体的汽车,具有自己的品牌和颜色属性值。
car1 = Car("Toyota", "Red")
car2 = Car("Ford", "Blue")
这里,car1
和car2
是Car
类的两个对象,它们分别代表了两辆不同的汽车。尽管它们都是由同一个Car
类创建的,但每个对象都拥有自己的属性值,且在内存中占用独立的空间。
总结
- 类是创建对象的蓝图或模板,它定义了构成对象的属性和方法。
- 对象是类的实例,是根据类模板创建的具体实体,拥有类定义的属性和方法。
- 类是抽象的定义,而对象是具体的实例。
Python中的构造方法:
在Python中,构造方法由__init__
方法实现。当你创建类的新实例时,__init__
方法会被自动调用。
__init__
方法的第一个参数总是self
,它代表类的实例本身。这与其他面向对象语言中的this
关键字相似。__init__
可以有额外的参数,这些参数在创建类的实例时传递,用于初始化对象的属性或执行任何初始设置。
class Person:
def __init__(self, name, age):
self.name = name # 创建一个名为name的实例变量,并将其设置为传入的name参数
self.age = age # 创建一个名为age的实例变量,并将其设置为传入的age参数
# 创建Person类的实例
person1 = Person("Alice", 30)
# 访问实例变量
print(person1.name) # 输出: Alice
print(person1.age) # 输出: 30
魔术方法:
类的封装:
私有成员只能被同类的其他成员使用
定义私有成员
私有成员是通过在成员名称前添加双下划线__
来定义的。这告诉Python解释器对这些成员名进行改写,以防止它们在类外部被访问。
class MyClass:
def __init__(self):
self.__private_variable = "I am private"
def __private_method(self):
print("This is a private method.")
在这个例子中,__private_variable
和__private_method
都是私有的,只能在MyClass
内部访问。
访问私有成员
尽管主要目的是隐藏,但Python提供了一种方式来访问类的私有成员。这是通过名称改写(name mangling)实现的。Python解释器自动将任何以双下划线开始并且不以双下划线结束的名称转换为_ClassName__memberName
形式。
instance = MyClass()
print(instance._MyClass__private_variable) # 访问私有变量
instance._MyClass__private_method() # 调用私有方法
单继承:
在面向对象编程(OOP)中,继承是一种允许我们定义一个类(称为子类)来继承另一个类(称为父类或基类)的属性和方法的机制。通过继承,子类可以扩展或修改父类的行为。继承支持代码复用和封装,是OOP中的一个核心概念。
基本用法
在Python中,继承可以通过在类定义时,在类名后面的括号中指定父类来实现。
class Parent:
def __init__(self):
self.value = "Inside Parent"
def show(self):
print(self.value)
class Child(Parent):
def __init__(self):
# 调用父类的__init__方法
super().__init__()
self.value = "Inside Child"
# 创建Child类的实例
child_instance = Child()
child_instance.show() # 输出: Inside Child
方法重写(Overriding)
子类可以重写继承自父类的方法,以提供特定于子类的行为。
class Parent:
def myMethod(self):
print('调用父类方法')
class Child(Parent):
def myMethod(self):
print('调用子类方法')
child = Child() # 子类实例
child.myMethod() # 输出: 调用子类方法
多重继承
Python还支持多重继承,允许一个子类同时继承多个父类。
class Base1:
def method(self):
print('Base1 method')
class Base2:
def method(self):
print('Base2 method')
class MultiDerived(Base1, Base2):
pass
multi_derived_instance = MultiDerived()
multi_derived_instance.method() # 输出: Base1 method
使用继承的建议
- 明确继承的用途:使用继承来表示"is-a"关系,确保子类是父类的特化。
- 优先使用组合而非继承:如果"is-a"关系不明确,可能组合(将其他类的对象作为属性)是更好的选择。
- 注意继承带来的复杂性:特别是在使用多重继承时,确保清晰地理解MRO和各个父类之间的交互。
多态:
在面向对象编程(OOP)中,多态(Polymorphism)是一种使用对象的概念,使得不同的类可以通过同一个接口进行操作,而具体使用哪个类的实现则可以在运行时(动态)决定。多态性意味着“多种形态”,它允许不同类的对象响应相同的消息(或方法调用),但是每个类可以根据需要提供这个消息的特定实现。这样,同一个接口可以用于不同的底层形式(类型)的对象。
多态的实现
在Python中,多态是隐式实现的,因为Python是动态类型语言。你不需要在代码中显式声明接口或继承关系,Python会自动处理方法和属性的调用。
class Dog:
def speak(self):
return "Woof!"
class Cat:
def speak(self):
return "Meow!"
def animal_sound(animal):
print(animal.speak())
# 创建Dog和Cat的实例
dog = Dog()
cat = Cat()
# 不同的对象调用相同的函数
animal_sound(dog) # 输出: Woof!
animal_sound(cat) # 输出: Meow!
在这个例子中,函数animal_sound
可以接受任何包含speak
方法的对象。Dog
和Cat
类都实现了speak
方法,因此它们都可以被animal_sound
函数使用。这就是多态性的体现:不同的对象可以通过相同的接口animal_sound
来执行,而具体行为(输出)则依赖于对象的实际类型。
多态的好处
- 提高代码的灵活性:你可以写出更通用的代码来处理不同类型的对象,而不需要知道对象的具体类型。
- 提高代码的可扩展性:在现有代码基础上添加新的类变得更加简单,因为新类只需要实现必要的方法即可,无需修改使用这些对象的代码。
- 增强代码的可维护性:通过减少代码间的依赖,使得修改一个类的实现时,不必修改依赖于该类的其他代码。