Python学习笔记-基础篇

格式化输出

%[(name)][flags][width].[precision] typecode
(name) :可选,用于选择指定的 key
flags:可选,可供选择的值有:
– + 右对齐:正数的加正号,负数的加负号
– - 左对齐:正数前没有负号,负数前加负号
width:可选,占有宽度
precision:可选,小数点后保留的位数
typecode: 必选,类型码
– s,获取传入的对象__str__方法的返回值,并将其格式化到指定位置
– r,获取传入对象的__repr__方法的返回值,并将其格式化到指定位置
– c,整数:将数字转换成其 unicode 对应的值,10 进制范围为 0 <= i <=1114111
– o,将整数转换成八进制表示,并将其格式化到指定位置
– x,将整数转换成 16 进制,并将其格式化到指定位置
– d,将整数,浮点数转化为十进制表示,并将其格式化到指定位置

print('I am %s, age %d' % ('Mary', 18))  # 输出:I am Mary, age 18
print('I am %(x)s, age %(y)d' % {'x':'Mary', 'y': 18})  # 输出:I am Mary, age 18
print("I am {}, age {}".format('Mary', 18))  # 输出:I am Mary, age 18
print("I am {0}, age {1}".format('Mary', 18))  # 输出:I am Mary, age 18
print('My score is %.3f' % 90.500)  # 输出:My score is 90.500
print('My score is {:f}'.format(90.500))  # 输出:My score is 90.500000
print('%d%%' % (50))  # 输出:50%

print('{:>10}'.format('hello'))  # 右对齐,填充到10个字符长度
print('{:<10}'.format('hello'))  # 左对齐
print('{:^10}'.format('hello'))  # 居中对齐
print('{hello:>10}'.format(hello='world'))  # 右对齐
print('{hello:>10}'.format(**{'hello': 'world'}))  # 右对齐
print('hello'.rjust(10))  # 右对齐
print('hello'.ljust(10))  # 左对齐
print('hello'.center(10))  # 居中对齐
print('hello'.rjust(10, '*'))  # 右对齐,填充字符为星号

print(f"{variable:>30}") 
print(f"{variable:<30}") 
print(f"{variable:^30}")
print(f"{variable:*^30}")  # 填充字符为星号
 
from datetime import datetime
now = datetime.now()
print(f"Date: {now:%d-%m-%Y}")
print(f"Time: {now:%H:%M:%S}")
print(f"Locale's Date and Time: {now:%c}")
print(f"Time in AM/PM format: {now:%I:%M %p}")
 
n = 1000000000
print(f"{n:_}") # Outputs: 1_000_000_000
print(f"{n:,}") # Outputs: 1,000,000,000

num = 13.234 
print(f"{num:.2f}") # Result: 13.23
print(f"{num:.0f}") # Result: 13
print(f"{num:,.2%}") # Result: 1,323.40%
value = 0.75321 
print(f"{value:.2%}") # Output: 75.32%

name,age = "John",18
print(f"我是{name},我今年{age}岁了。") 
a = "test"
print(f"{{{a}}}")  # 输出:{test}

# 使用r前缀创建原始字符串
path = r'C:\Users\Username\Documents'
print(path)
# 使用b前缀创建字节字符串
binary_data = b'\x48\x65\x6c\x6c\x6f'  # 字母 'Hello' 的字节表示
print(binary_data)
# 使用u前缀创建Unicode字符串(Python 2示例)
unicode_text = u'你好,世界!'
print(unicode_text)
# 使用f前缀创建格式化字符串
name = 'Alice'
age = 30
greeting = f'Hello, my name is {name} and I am {age} years old.'
print(greeting)

复现随机数

import random
x = random.getstate()
print(random.randint(1,10))
print(random.randint(1,10))
print(random.randint(1,10))
random.setstate(x)
print(random.randint(1,10))
print(random.randint(1,10))
print(random.randint(1,10))

浮点数精度运算函数decimal

# 浮点数采用E记法(科学计数法),所以如果要获得完全精准的浮点数,则需要使用decimal函数
import decimal
a = decimal.Decimal('0.1')
b = decimal.Decimal('0.2')
c = decimal.Decimal('0.3')
print(c)
print(a+b == c)
True

复数

# 复数分为实部和虚部,real和imag可以分别获取复数的实部和虚部x = 1+2j
print(x.real)
1.0
print(x.imag)
2.0

同时获取整除(向下取整)和取余函数divmod()

divmod(3,2)
(1,1)

幂运算函数pow()

# pow()还支持扩展参数--pow(x,y,z),计算x的y次方,然后将结果与z进行求余运算
pow(2,3,5)
3

布尔值类型

False
# 1、定义为False的对象:None和False
# 2、值为0的数字类型:0,0j,0.0,Decimal(0),Fraction(0,1)
# 3、空的序列和集合:‘’,[],{},set(),range(0)

True == 1
False == 0

# 逻辑运算优先级 not>and>or

条件表达式

x = 10
result = "greater than 5" if x > 5 else "less than or equal to 5"
print(result)

循环else语句

for i in range(1,10):
    # 重复执行的代码
else:
    # 循环正常结束后要执行的代码

count = 0
while count < 5:
    # 重复执行的代码
    count += 1
else:
    # 循环正常结束后要执行的代码

# 不管是while还是for只要遇到break,else下方的代码都是不执行的

切片

s = [1, 2, 3, 4, 5]
s[len(s):] = [6] # == s.append(6)
s[len(s):] = [7, 8, 9] # == s.extend([7, 8, 9])

创建不可变集合

# frozenset(iterable)

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

操作已排序列表

import bisect

# 创建一个已排序的列表
my_list = [1, 3, 5, 7, 9]

# 使用 bisect.insort 插入新元素并保持列表排序
bisect.insort(my_list, 4)
print(my_list)  # 输出: [1, 3, 4, 5, 7, 9]

# 使用 bisect.bisect_left 查找插入位置(左侧边界)
position = bisect.bisect_left(my_list, 6)
print(position)  # 输出: 4

数组

from array import array

# 创建一个有符号整数数组
int_array = array('i', [1, 2, 3, 4, 5])

# 打印数组的类型码和元素
print(f"Array type code: {int_array.typecode}")  # 输出: 'i'
print(f"Array elements: {int_array}")           # 输出: array('i', [1, 2, 3, 4, 5])

# 添加一个新元素到数组中
int_array.append(6)
print(f"After appending 6: {int_array}")         # 输出: array('i', [1, 2, 3, 4, 5, 6])

# 使用索引访问和修改数组元素
print(f"Element at index 2: {int_array[2]}")     # 输出: 3
int_array[2] = 10
print(f"After updating index 2: {int_array}")    # 输出: array('i', [1, 2, 10, 4, 5, 6])

# 删除指定索引处的元素
del int_array[3]
print(f"After deleting index 3: {int_array}")    # 输出: array('i', [1, 2, 10, 5, 6])

# 将数组转换为列表
list_from_array = list(int_array)
print(f"List from array: {list_from_array}")     # 输出: [1, 2, 10, 5, 6]

浅拷贝与深拷贝

# 浅拷贝(Shallow Copy)与深拷贝(Deep Copy)是数据复制中的两种方式,主要用于Python中的对象复制。
# 浅拷贝:拷贝父对象,不会递归拷贝内部的子对象。
# 深拷贝:递归拷贝父对象及其内部的所有子对象。
# 在Python中,可以使用copy模块的copy()函数进行浅拷贝,使用deepcopy()函数进行深拷贝。

import copy
 
# 定义一个嵌套结构的对象
original = [1, 2, [3, 4]]

# 浅拷贝
shallow_copy = copy.copy(original)

# 深拷贝
deep_copy = copy.deepcopy(original)
 
# 修改原始对象
original[2][0] = "changed"
 
# 输出浅拷贝和深拷贝结果
print("Shallow Copy:", shallow_copy)  # 输出: [1, 2, ['changed', 4]]
print("Deep Copy:", deep_copy)        # 输出: [1, 2, [3, 4]]
# 浅拷贝中,原始列表中的子列表并没有被复制,浅拷贝后的对象和原始对象中的子对象会指向同一个内存地址。
# 而深拷贝会创建子对象的新副本,原始对象和拷贝后的对象中的子对象会指向不同的内存地址。

推导式

# 列表推导式:使用 [...] 创建一个新的列表。
[expression for item in collection if condition]
# 集合推导式:使用 {...} 创建一个新的集合。
{expression for item in collection if condition}
# 字典推导式:使用 {key: value for ...} 创建一个新的字典。
{key: value for (key, value) in iterable if condition}
# 生成器推导式:使用 (...) 创建一个生成器对象。
(expression for item in collection if condition)

# 列表推导式
square_numbers = [x * x for x in range(1, 6)]
print(square_numbers)  # 输出: [1, 4, 9, 16, 25]

numbers = [1, 2, 3, 4, 5]
squares = [num**2 for num in numbers if num % 3 == 0]
print(squares)  # 输出: [9, 16]

# 集合推导式
words = ["apple", "banana", "cherry"]
word_lengths = {len(word) for word in words}
print(word_lengths)  # 输出: {5, 6}

numbers = [3, 8, 12, 16, 20]
squares = {x**2 for x in numbers if x > 10}
print(squares)  # 输出: {144, 256, 225}

# 字典推导式
numbers = {x: x**2 for x in range(10)}
# 结果: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

data = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
result = {k: v for (k, v) in data.items() if k in ['a', 'b', 'c']}
# 结果: {'a': 1, 'b': 2, 'c': 3}

# 生成器推导式
square_numbers_generator = (x * x for x in range(1, 6))
print(square_numbers_generator)  # 输出: <generator object <genexpr> at 0x...>

for num in square_numbers_generator:
    print(num)  # 输出: 1, 4, 9, 16, 25

序列化与反序列化

# pickle模块用于序列化和反序列化Python对象结构。"Pickle"是Python对象的二进制表示,可以保存到文件中,或在进程间传输。
# pickle模块提供了四个功能:dump(), load(), dumps(), loads()。

# pickle.dump(obj, file, [protocol]):将对象obj保存到文件file中。protocol是序列化的协议,默认值为0,表示以文本的形式序列化。protocol的值为1或True表示以二进制的形式序列化。
import pickle
my_list = [123, 3.14, 'Hello', None]
# 创建文件并写入
with open('pickle_example.pkl', 'wb') as my_file:
    pickle.dump(my_list, my_file)


#pickle.load(file):从file文件中读取数据,并返回被序列化的对象。
import pickle
with open('pickle_example.pkl', 'rb') as my_file:
    my_list = pickle.load(my_file)
print(my_list)  # 输出:[123, 3.14, 'Hello', None]

# pickle.dumps(obj, [protocol]):将对象obj转换为一个字节流(bytes)。
import pickle
my_list = [123, 3.14, 'Hello', None]
my_bytes = pickle.dumps(my_list)
print(my_bytes)  # 输出:一串二进制字节

# pickle.loads(bytes_object):从字节流(bytes)中读取对象。
import pickle
my_bytes = b'\x80\x03]q\x00(K\x00K?\x85q\x01cbuiltin_module_tq\x02X\x06\x00\x00\x00floatq\x03\x8c\x0bu.'
my_list = pickle.loads(my_bytes)
print(my_list)  # 输出:[123, 3.14, 'Hello', None]

# 注意:pickle模块不是安全的。当unpickle对象时,对象的类定义和模块必须可用。如果不是由可信的源进行unpickle操作,那么可能会导致安全问题。

异常

def divide(x, y):
    try:
        result = x / y
    except ZeroDivisionError:
        print("错误:除数不能为0")
    except TypeError:
        print("错误:参数需要是数字类型")
    except Exception as e:
        print(f"未知错误:{e}")
    else:
        print("程序没有发生异常")
        return result
    finally:
        print("程序是否异常都会打印")
 
# 示例调用
print(divide(10, 0))
print(divide(10, 2))
print(divide("a", 2))


# 使用 raise 引发自定义异常
class CustomError(Exception):
    pass
 
def raise_custom_error():
    raise CustomError("发生了一个自定义异常")
 
# 使用 assert 语句检查条件是否满足
def check_condition(condition):
    assert condition, "条件不满足"
 
# 示例函数调用
try:
    raise_custom_error()
except CustomError as e:
    print(e)
 
# 检查条件是否满足,如果不满足则会引发 AssertionError
try:
    check_condition(False)
except AssertionError as e:
    print(e)

垃圾回收机制

1. 引用计数(Reference Counting)
引用计数是 Python 内置的内存管理机制。每个对象都有一个引用计数,当一个对象被引用时,计数器增加,当引用被删除时,计数器减少。当引用计数降为零时,该对象会被立即回收。
2. 标记-清除(Mark-and-Sweep)
标记-清除是一种基于跟踪的垃圾收集算法,用来处理循环引用问题。Python 的垃圾收集器会周期性地暂停程序执行,检查所有对象,标记出可达的对象,随后清除未被标记的对象。
3. 分代收集(Generational Garbage Collection)
Python 的垃圾收集器还使用了分代收集策略,将对象分为不同的代,根据对象的存活时间长短进行分类和处理。主要分为三代:年轻代、中生代和老年代。
posted @ 2024-06-23 14:38  wanghongwei-dev  阅读(8)  评论(0编辑  收藏  举报