可以赋值给一个变量
可以添加到集合对象中
可以作为参数传递给函数
可以当作函数的返回值
a = 1
type(1) # class 'int'
type(int) # class 'type'
class Student():
pass
class MyStudent(Student):
pass
Student.__bases__ # (<class 'object'>,)
MyStudent.__bases__ # (<class '__main__.Student'>,)
type.__bases__ # (<class 'object'>,)
object.__bases__ # ()
对象的三个特征:
a = None
b = None
print(a == b) # True
class MyClass:
def __new__(cls, *args, **kwargs):
print("Creating instance")
return super().__new__()
class MyClass:
def __init__(self, value):
self.value = value
class MyClass:
def __del__(self):
print("Object deleted")
class Company(object):
def __init__(self, employee_list):
self.employee = employee_list
def __str__(self):
return ', '.join(self.employee)
company = Company(['zhangsan', 'lisi', 'wangwu'])
print(company) # <__main__.Company object at 0x0000026421401F10> # 使用__str__: zhangsan, lisi, wangwu
class Company(object):
def __init__(self, employee_list):
self.employee = employee_list
def __str__(self):
return ', '.join(self.employee)
def __repr__(self):
return ', '.join(self.employee)
company = Company(['zhangsan', 'lisi', 'wangwu'])
# print(company) # <__main__.Company object at 0x0000026421401F10> # 使用__str__: zhangsan, lisi, wangwu
company # 在开发环境下会使用__repr__: zhangsan, lisi, wangwu
class Point:
def __eq__(self, other):
return self.x == other.x and self.y == other.y
class Point:
def __ne__(self, other):
return not self.__eq__(other)
class Point:
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
class MyClass:
def __getattr__(self, name):
return f"{name} does not exist"
class MyClass:
def __setattr__(self, name, value):
print(f"Setting {name} to {value}")
super().__setattr__(name, value)
class MyClass:
def __delattr__(self, name):
print(f"Deleting {name}")
super().__delattr__(name)
class MyList:
def __len__(self):
return 10
class MyList:
def __getitem__(self, index):
return index * 2
class MyList:
def __setitem__(self, index, value):
print(f"Setting {index} to {value}")
class MyList:
def __delitem__(self, index):
print(f"Deleting {index}")
class MyList:
def __contains__(self, item):
return item % 2 == 0
class Adder:
def __call__(self, x, y):
return x + y
class MyContext:
def __enter__(self):
print("Entering context")
return self
class MyContext:
def __exit__(self, exc_type, exc_value, traceback):
print("Exiting context")
class MyRange:
def __init__(self, start, end):
self.start = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.start >= self.end:
raise StopIteration
current = self.start
self.start += 1
return current
class Point:
def __hash__(self):
return hash((self.x, self.y))
class MyClass:
def __bool__(self):
return False
class MyClass:
def __dir__(self):
return ["x", "y"]
# 多态实现方式1:Python 的多态主要依赖于鸭子类型。只要对象具有所需的方法或属性,就可以在特定的上下文中使用,而不需要显式地继承某个类或实现某个接口。
class Dog:
def speak(self):
return "Woof!"
class Cat:
def speak(self):
return "Meow!"
def animal_sound(animal):
print(animal.speak())
dog = Dog()
cat = Cat()
animal_sound(dog) # 输出: Woof!
animal_sound(cat) # 输出: Meow!
# 多态实现方式2:Python 也支持通过继承实现多态。子类可以重写父类的方法,从而表现出不同的行为。
class Animal:
def speak(self):
raise NotImplementedError("Subclasses must implement this method")
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
def animal_sound(animal):
print(animal.speak())
dog = Dog()
cat = Cat()
animal_sound(dog) # 输出: Woof!
animal_sound(cat) # 输出: Meow!
from abc import ABC, abstractmethod
class MyClass(ABC):
@abstractmethod
def do_something(self):
pass
from collections.abc import Iterable
class MyList:
def __iter__(self):
return iter([1, 2, 3])
print(isinstance(MyList(), Iterable)) # 输出: True
from abc import ABC
class Animal(ABC):
@abstractmethod
def speak(self):
pass
class Dog: # 未继承 Animal,但注册为 Animal 的子类
def speak(self):
return "Woof!"
Animal.register(Dog) # 注册 Dog 为 Animal 的“虚拟子类”
print(issubclass(Dog, Animal)) # 输出: True
dog = Dog()
print(isinstance(dog, Animal)) # 输出: True
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
def animal_sound(animal):
print(animal.speak())
dog = Dog()
cat = Cat()
animal_sound(dog) # 输出: Woof!
animal_sound(cat) # 输出: Meow!
is 与 == 的区别:
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True(值相等)
print(a is b) # False(内存地址不同)
type() 和 isinstance() 的区别:
class Animal:
pass
class Dog(Animal):
pass
dog = Dog()
# 使用 type()
print(type(dog) == Dog) # True
print(type(dog) == Animal) # False(无法检查继承关系)
# 使用 isinstance()
print(isinstance(dog, Dog)) # True
print(isinstance(dog, Animal)) # True(支持继承关系检查)
类变量(Class Variable):
class MyClass:
class_var = 10 # 类变量
# 通过类名访问
print(MyClass.class_var) # 输出: 10
# 通过实例访问
obj1 = MyClass()
obj2 = MyClass()
print(obj1.class_var) # 输出: 10
print(obj2.class_var) # 输出: 10
# 修改类变量(通过类名)
MyClass.class_var = 20
print(obj1.class_var) # 输出: 20
print(obj2.class_var) # 输出: 20
# 修改类变量(通过实例)
obj1.class_var = 30 # 实际上创建了一个实例变量
print(obj1.class_var) # 输出: 30(实例变量)
print(obj2.class_var) # 输出: 20(类变量未变)
对象变量(实例变量,Instance Variable):
class MyClass:
def __init__(self, value):
self.instance_var = value # 实例变量
obj1 = MyClass(10)
obj2 = MyClass(20)
print(obj1.instance_var) # 输出: 10
print(obj2.instance_var) # 输出: 20
# 修改实例变量
obj1.instance_var = 30
print(obj1.instance_var) # 输出: 30
print(obj2.instance_var) # 输出: 20(不受影响)
MRO的规则:
查看 MRO:
class A:
pass
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
print(D.__mro__)
# 输出: (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
对象(实例)方法(Instance Method):
class MyClass:
def instance_method(self):
print("This is an instance method")
print(f"Called by: {self}")
obj = MyClass()
obj.instance_method() # 通过实例调用
类方法(Class Method):
class MyClass:
class_attr = 10
@classmethod
def class_method(cls):
print("This is a class method")
print(f"Called by: {cls}")
print(f"Class attribute: {cls.class_attr}")
MyClass.class_method() # 通过类调用
obj = MyClass()
obj.class_method() # 通过实例调用
静态方法(Static Method):
class MyClass:
@staticmethod
def static_method():
print("This is a static method")
MyClass.static_method() # 通过类调用
obj = MyClass()
obj.static_method() # 通过实例调用
私有属性的定义:
class MyClass:
def __init__(self, value):
self.__private_attr = value # 私有属性
def get_private_attr(self):
return self.__private_attr # 通过方法访问私有属性
def set_private_attr(self, value):
self.__private_attr = value # 通过方法修改私有属性
obj = MyClass(10)
print(obj.get_private_attr()) # 输出: 10
obj.set_private_attr(20)
print(obj.get_private_attr()) # 输出: 20
# 直接访问私有属性会报错
# print(obj.__private_attr) # AttributeError: 'MyClass' object has no attribute '__private_attr'
# 通过访问改写的名称进行访问
print(obj._MyClass__private_attr) # 输出: 20
受保护属性:
class MyClass:
def __init__(self, value):
self._protected_attr = value # 受保护属性
obj = MyClass(10)
print(obj._protected_attr) # 输出: 10(可以访问,但不建议)
数据封装的实现方式:
class Person:
def __init__(self, name, age):
self.__name = name # 私有属性
self.__age = age # 私有属性
def get_name(self):
return self.__name # getter 方法
def set_name(self, name):
self.__name = name # setter 方法
def get_age(self):
return self.__age # getter 方法
def set_age(self, age):
if age > 0:
self.__age = age # setter 方法
else:
print("Age must be positive")
person = Person("Alice", 30)
print(person.get_name()) # 输出: Alice
person.set_age(-10) # 输出: Age must be positive
class Person:
def __init__(self, name, age):
self.__name = name # 私有属性
self.__age = age # 私有属性
@property
def name(self):
return self.__name # getter
@name.setter
def name(self, name):
self.__name = name # setter
@property
def age(self):
return self.__age # getter
@age.setter
def age(self, age):
if age > 0:
self.__age = age # setter
else:
print("Age must be positive")
person = Person("Alice", 30)
print(person.name) # 输出: Alice
person.age = -10 # 输出: Age must be positive
自省的作用:
常用的自省工具:
num = 42
print(type(num)) # 输出: <class 'int'>
class Animal:
pass
class Dog(Animal):
pass
dog = Dog()
print(isinstance(dog, Animal)) # 输出: True
a = [1, 2, 3]
print(id(a)) # 输出: 内存地址(如 140123456789)
s = "hello"
print(dir(s)) # ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', .....]
class MyClass:
def __init__(self, x, y):
self.x = x
self.y = y
obj = MyClass(10, 20)
print(obj.__dict__) # 输出: {'x': 10, 'y': 20}
class MyClass:
attr = 10
obj = MyClass()
print(hasattr(obj, 'attr')) # 输出: True
print(hasattr(obj, 'method')) # 输出: False
class MyClass:
attr = 10
obj = MyClass()
print(getattr(obj, 'attr')) # 输出: 10
print(getattr(obj, 'unknown', 'default')) # 输出: default
class MyClass:
pass
obj = MyClass()
setattr(obj, 'attr', 20)
print(obj.attr) # 输出: 20
class Parent:
def __init__(self, name):
self.name = name
print("Parent initialized")
class Child(Parent):
def __init__(self, name, age):
super().__init__(name) # 调用父类的 __init__ 方法
self.age = age
print("Child initialized")
child = Child("Alice", 10)
# 输出:
# Parent initialized
# Child initialized
"""
MRO 顺序:D -> B -> C -> A
super() 按照 MRO 顺序依次调用父类的 __init__ 方法
"""
class A:
def __init__(self):
print("A initialized")
class B(A):
def __init__(self):
super().__init__()
print("B initialized")
class C(A):
def __init__(self):
super().__init__()
print("C initialized")
class D(B, C):
def __init__(self):
super().__init__()
print("D initialized")
d = D()
# 输出:
# A initialized
# C initialized
# B initialized
# D initialized
super([type[, object_or_type]])
class Parent:
def greet(self):
print("Hello from Parent")
class Child(Parent):
def greet(self):
super(Child, self).greet() # 显式调用父类方法
print("Hello from Child")
child = Child()
child.greet()
# 输出:
# Hello from Parent
# Hello from Child
try:
f_read = open("example.txt")
print("start ...")
raise KeyError
f_read.close()
except KeyError as e:
print("key error...")
f_read.close()
else:
print("other error...")
finally:
print("finally...")
f_read.close()
with 语句的作用:
with 语句的基本用法:
with 上下文管理器 as 变量:
代码块
with open("example.txt", "r") as file:
content = file.read()
print(content)
上下文管理器:
# 自定义上下文管理器
class MyContextManager:
def __enter__(self):
print("Entering the context")
return self
def __exit__(self, exc_type, exc_value, traceback):
print("Exiting the context")
if exc_type is not None:
print(f"Exception occurred: {exc_value}")
return True # 抑制异常
with MyContextManager() as cm:
print("Inside the context")
raise ValueError("An error occurred")
# 输出:
# Entering the context
# Inside the context
# Exiting the context
# Exception occurred: An error occurred
from contextlib import contextmanager
@contextmanager
def my_context_manager():
print("Entering the context")
try:
yield "Resource"
finally:
print("Exiting the context")
with my_context_manager() as resource:
print(f"Inside the context, using {resource}")
# 输出:
# Entering the context
# Inside the context, using Resource
# Exiting the context
from contextlib import closing
from urllib.request import urlopen
with closing(urlopen("https://www.example.com")) as page:
content = page.read()
print(content)
序列的特点:
容器序列和扁平序列:
可变序列与不可变序列:
数组array和列表list的区别:
+ 操作符:
lst1 = [1, 2]
lst2 = [3, 4]
result = lst1 + lst2
print(result) # 输出: [1, 2, 3, 4]
print(lst1) # 输出: [1, 2](原列表未修改)
+= 操作符:
lst1 = [1, 2]
lst2 = [3, 4]
lst1 += lst2
print(lst1) # 输出: [1, 2, 3, 4](原列表被修改)
print(lst2) # 输出: [3, 4](右侧列表未修改)
extend() 方法:
lst1 = [1, 2]
lst2 = [3, 4]
lst1.extend(lst2)
print(lst1) # 输出: [1, 2, 3, 4](原列表被修改)
print(lst2) # 输出: [3, 4](右侧列表未修改)
append() 方法:
lst = [1, 2, 3]
lst.append(4)
print(lst) # 输出: [1, 2, 3, 4]
# 添加一个列表作为单个元素
lst.append([5, 6])
print(lst) # 输出: [1, 2, 3, 4, [5, 6]]
模式[start:end:step]
"""
其中,第一个参数 start 表示切片开始的位置,默认为 0;
第二个参数 end 表示切片截止(不包含)位置,默认为列表长度;
第三个参数 step 表示切片的步长,默认为 1。
当 start 为 0 时可以省略,当 end 为列表长度时可以省略,当 step 为 1 时可以省略,并且省略最后一个冒号“:”。
另外,当 step 为负整数时,表示反向切片,这是 start 应该比 end 的值要大才行。
"""
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 提取索引 2 到 5 的元素
print(lst[2:6]) # 输出: [2, 3, 4, 5]
# 提取从开头到索引 4 的元素
print(lst[:5]) # 输出: [0, 1, 2, 3, 4]
# 提取从索引 5 到末尾的元素
print(lst[5:]) # 输出: [5, 6, 7, 8, 9]
# 提取整个序列
print(lst[:]) # 输出: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 每隔一个元素提取一次
print(lst[::2]) # 输出: [0, 2, 4, 6, 8]
# 反转序列
print(lst[::-1]) # 输出: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
# 从索引 2 到 8,每隔两个元素提取一次
print(lst[2:8:2]) # 输出: [2, 4, 6]
# 提取最后三个元素
print(lst[-3:]) # 输出: [7, 8, 9]
# 提取从倒数第 5 个到倒数第 2 个元素
print(lst[-5:-1]) # 输出: [5, 6, 7, 8]
# 修改索引 2 到 5 的元素
lst[2:6] = [10, 11, 12]
print(lst) # 输出: [0, 1, 10, 11, 12, 5, 6, 7, 8, 9]
# 删除索引 2 到 5 的元素
lst[2:6] = []
print(lst) # 输出: [0, 1, 6, 7, 8, 9]
# 等价于以下使用del方式删除
# del lst[2:6]
# print(lst) # 输出: [0, 1, 6, 7, 8, 9]
import numbers
class Group:
"""
支持切片操作
group_name:组名称
company_name:组所属公司名称
staffs:员工
"""
def __init__(self, group_name, company_name, staffs):
self.group_name = group_name
self.company_name = company_name
self.staffs = staffs
def __getitem__(self, item):
cls = type(self)
# print("cls =>", cls, cls.__mro__, isinstance(item, slice)) # <class '__main__.Group'> (<class '__main__.Group'>, <class 'object'>) True
if isinstance(item, slice):
return cls(group_name=self.group_name, company_name=self.company_name, staffs=self.staffs[item])
elif isinstance(item, numbers.Integral):
return cls(group_name=self.group_name, company_name=self.company_name, staffs=[self.staffs[item]])
def __str__(self):
return str(self.staffs)
def __len__(self):
return len(self.staffs)
def __contains__(self, item):
if item in self.staffs:
return True
else:
return False
def __iter__(self):
return iter(self.staffs)
def __reversed__(self):
self.staffs.reverse()
staffs = ["str", "int", "name", "age"]
group = Group(group_name='user', company_name="Company", staffs=staffs)
print(group) # ['str', 'int', 'name', 'age']
# 实现切片 __getitem__
# print(group[0:2]) # ['str', 'int']
# 计算列表长度 __len__
# print(len(group)) # 4
# 判断是否包含 __contains__
# if "str" in group:
# print("True") # True
# else:
# print("False") # False
# 可迭代 __iter__
# for item in group:
# print("item=>", item) # str in name age
# 列表反转 __reversed__
# reversed(group)
# print(group) # ['age', 'name', 'int', 'str']
bisect 模块的核心功能:
需要保持序列严格升序时使用
import bisect
lst = [1, 2, 3, 4, 4, 4, 5]
pos_l = bisect.bisect_left(lst, 4)
print(pos_l) # 3
pos_r = bisect.bisect_right(lst, 4)
print(pos_r) # 6
bisect.insort_left(lst, 2)
print(lst) # [1, 2, 2, 3, 4, 4, 4, 5]
bisect.insort_right(lst, 10)
print(lst) # [1, 2, 2, 3, 4, 4, 4, 5, 10]
array 和 list 的区别:
import array
my_arr = array.array('i')
my_arr.append(1)
my_arr.append(3)
print(my_arr) # array('i', [1, 3])
# 语法
[表达式 for 元素 in 可迭代对象 if 条件]
# 生成 1 到 10 的平方列表
squares = [x ** 2 for x in range(1, 11)]
print(squares) # 输出: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# 过滤出偶数
evens = [x for x in range(10) if x % 2 == 0]
print(evens) # 输出: [0, 2, 4, 6, 8]
返回一个列表。
适合生成小型列表。
# 语法
(表达式 for 元素 in 可迭代对象 if 条件)
# 生成 1 到 10 的平方生成器
squares_gen = (x ** 2 for x in range(1, 11))
print(squares_gen) # 输出: <generator object <genexpr> at 0x...>
# 使用生成器
for num in squares_gen:
print(num, end=" ") # 输出: 1 4 9 16 25 36 49 64 81 100
返回一个生成器对象。
惰性求值,节省内存。
适合生成大型数据集。
{键表达式: 值表达式 for 元素 in 可迭代对象 if 条件}
# 生成数字到其平方的字典
squares_dict = {x: x ** 2 for x in range(1, 6)}
print(squares_dict) # 输出: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# 过滤出偶数并生成字典
evens_dict = {x: x ** 2 for x in range(10) if x % 2 == 0}
print(evens_dict) # 输出: {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
返回一个字典。
适合生成键值对数据。
{表达式 for 元素 in 可迭代对象 if 条件}
# 生成 1 到 10 的平方集合
squares_set = {x ** 2 for x in range(1, 11)}
print(squares_set) # 输出: {64, 1, 4, 36, 100, 9, 16, 49, 81, 25}
# 过滤出偶数并生成集合
evens_set = {x for x in range(10) if x % 2 == 0}
print(evens_set) # 输出: {0, 2, 4, 6, 8}
返回一个集合。
自动去重。