文章目录
- 前言
- 一、isinstance(obj, cls) 和 issubclass(sub, super)
- 二、反射
- 三、__setattr__、__delattr__、__getattr__
- 四、二次加工标准类型(包装)
- 五、__getattribute__
- 六、描述符(__get__、__set__、__delete__)
- 七、再看 property
- 八、__setitem__、__getitem__、__delitem__
- 九、__str__、__repr__、__format__
- 十、__next__和 __iter__ 实现迭代器协议
- 十一、__doc__
- 十二、__module__ 和 __class__
- 十三、__del__
- 十四、__enter__ 和 __exit__
- 十五、__call__
- 十六、metaclass
- 结语
前言
Python是一种强大且易于学习的编程语言。通过这个21天的计划,我们将逐步深入面向对象高级。无论你是初学者还是有一定基础的开发者,这个计划都将帮助你巩固和扩展你的Python知识。
在学习本篇之前,我们先复习一下前面的内容:
day1:Python下载和开发工具介绍
day2:数据类型、字符编码、文件处理
day3:基础语法与课外练习
day4:函数简单介绍
day5:模块与包
day6:常用模块介绍
day7:面向对象
一、isinstance(obj, cls) 和 issubclass(sub, super)
功能介绍
- isinstance(obj, cls):用于检查对象 obj是否是类 cls或其派生类的实例。
- issubclass(sub, super):用于检查类 sub是否是类 super的子类。
代码示例
class Animal:
pass
class Dog(Animal):
pass
dog = Dog()
# 检查对象是否是某个类的实例
print(isinstance(dog, Dog)) # 输出: True
print(isinstance(dog, Animal)) # 输出: True
# 检查类是否是某个类的子类
print(issubclass(Dog, Animal)) # 输出: True
二、反射
功能介绍
反射是指在运行时动态地获取对象的属性和方法,以及调用这些属性和方法。Python 提供了几个内置函数来实现反射,如 getattr()、setattr()、hasattr()和 delattr()。
代码示例
class Person:
def __init__(self, name):
self.name = name
def say_hello(self):
print(f"Hello, my name is {self.name}.")
p = Person("Alice")
# 检查对象是否有某个属性
print(hasattr(p, 'name')) # 输出: True
# 获取对象的属性
name = getattr(p, 'name')
print(name) # 输出: Alice
# 设置对象的属性
setattr(p, 'age', 25)
print(p.age) # 输出: 25
# 删除对象的属性
delattr(p, 'age')
print(hasattr(p, 'age')) # 输出: False
# 调用对象的方法
if hasattr(p, 'say_hello'):
method = getattr(p, 'say_hello')
method() # 输出: Hello, my name is Alice.
三、setattr、delattr、getattr
功能介绍
- setattr:当给对象的属性赋值时,会自动调用该方法。
- delattr:当删除对象的属性时,会自动调用该方法。
- getattr:当访问对象不存在的属性时,会自动调用该方法。
代码示例
class MyClass:
def __init__(self):
self.data = {}
def __setattr__(self, name, value):
if name == 'data':
# 正常设置 data 属性
super().__setattr__(name, value)
else:
# 将其他属性存储在 data 字典中
self.data[name] = value
def __delattr__(self, name):
if name in self.data:
del self.data[name]
else:
super().__delattr__(name)
def __getattr__(self, name):
if name in self.data:
return self.data[name]
else:
raise AttributeError(f"'MyClass' object has no attribute '{name}'")
obj = MyClass()
obj.x = 10
print(obj.x) # 输出: 10
del obj.x
print(hasattr(obj, 'x')) # 输出: False
四、二次加工标准类型(包装)
功能介绍
通过继承标准类型(如 list、dict 等),可以对其进行二次加工,添加额外的功能。
代码示例
class MyList(list):
def append_unique(self, item):
if item not in self:
super().append(item)
my_list = MyList()
my_list.append_unique(1)
my_list.append_unique(2)
my_list.append_unique(1)
print(my_list) # 输出: [1, 2]
五、getattribute
功能介绍
__getattribute__是在访问对象的任何属性时都会调用的方法。需要注意的是,如果在该方法中不小心再次访问对象的属性,可能会导致无限递归。
代码示例
class MyClass:
def __init__(self):
self.value = 10
def __getattribute__(self, name):
if name == 'value':
return super().__getattribute__(name) * 2
return super().__getattribute__(name)
obj = MyClass()
print(obj.value) # 输出: 20
六、描述符(get、set、delete)
功能介绍
描述符是一种实现了 get、__set__或 delete 方法的对象。它可以用来控制对象属性的访问、赋值和删除操作。
代码示例
class Integer:
def __init__(self, name):
self.name = name
def __get__(self, instance, owner):
if instance is None:
return self
return instance.__dict__[self.name]
def __set__(self, instance, value):
if not isinstance(value, int):
raise TypeError(f"{self.name} must be an integer.")
instance.__dict__[self.name] = value
def __delete__(self, instance):
del instance.__dict__[self.name]
class MyClass:
x = Integer('x')
obj = MyClass()
obj.x = 10
print(obj.x) # 输出: 10
try:
obj.x = 'abc'
except TypeError as e:
print(e) # 输出: x must be an integer.
七、再看 property
功能介绍
property是 Python 内置的一个装饰器,用于将方法转换为属性。它可以实现属性的只读、只写或读写操作。
代码示例
class Person:
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if not isinstance(value, str):
raise TypeError("Name must be a string.")
self._name = value
p = Person("Alice")
print(p.name) # 输出: Alice
p.name = "Bob"
print(p.name) # 输出: Bob
try:
p.name = 123
except TypeError as e:
print(e) # 输出: Name must be a string.
八、setitem、getitem、delitem
功能介绍
- setitem:当使用 obj[key] = value 形式给对象的某个键赋值时,会调用该方法。
- getitem:当使用 obj[key]形式获取对象的某个键的值时,会调用该方法。
- delitem:当使用 del obj[key] 形式删除对象的某个键时,会调用该方法。
代码示例
class MyDict:
def __init__(self):
self.data = {}
def __setitem__(self, key, value):
self.data[key] = value
def __getitem__(self, key):
return self.data[key]
def __delitem__(self, key):
del self.data[key]
my_dict = MyDict()
my_dict['a'] = 1
print(my_dict['a']) # 输出: 1
del my_dict['a']
try:
print(my_dict['a'])
except KeyError:
print("Key 'a' not found.")
九、str、repr、format
功能介绍
- str:用于返回对象的字符串表示,通常用于用户友好的输出。
- repr:用于返回对象的字符串表示,通常用于调试和开发。
- format:用于自定义对象的格式化输出。
代码示例
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"Point({self.x}, {self.y})"
def __repr__(self):
return f"Point({self.x}, {self.y})"
def __format__(self, format_spec):
if format_spec == 'r':
return f"({self.y}, {self.x})"
return str(self)
p = Point(1, 2)
print(str(p)) # 输出: Point(1, 2)
print(repr(p)) # 输出: Point(1, 2)
print(f"{p:r}") # 输出: (2, 1)
十、__next__和 iter 实现迭代器协议
功能介绍
迭代器是一种实现了 iter 和__next__ 方法的对象。__iter__方法返回迭代器对象本身,__next__方法返回迭代器的下一个元素。当没有更多元素时,抛出 StopIteration异常。
代码示例
class MyRange:
def __init__(self, start, end):
self.start = start
self.end = end
self.current = start
def __iter__(self):
return self
def __next__(self):
if self.current < self.end:
value = self.current
self.current += 1
return value
else:
raise StopIteration
my_range = MyRange(0, 3)
for num in my_range:
print(num) # 依次输出: 0, 1, 2
十一、doc
功能介绍
__doc__是一个特殊的属性,用于获取对象的文档字符串。文档字符串通常用于描述对象的功能和使用方法。
代码示例
class MyClass:
"""
This is a simple class.
"""
pass
print(MyClass.__doc__) # 输出: This is a simple class.
十二、module 和 class
功能介绍
- module:用于获取对象所属的模块名。
- class:用于获取对象所属的类。
代码示例
import math
class MyMath:
def __init__(self):
pass
m = MyMath()
print(m.__module__) # 输出: __main__
print(m.__class__) # 输出: <class '__main__.MyMath'>
print(math.sqrt.__module__) # 输出: math
十三、del
功能介绍
del 是一个析构方法,当对象被销毁时会自动调用该方法。通常用于释放对象占用的资源。
代码示例
class Resource:
def __init__(self):
print("Resource created.")
def __del__(self):
print("Resource destroyed.")
r = Resource()
del r # 输出: Resource destroyed.
十四、enter 和 exit
功能介绍
enter 和 __exit__方法用于实现上下文管理器协议。上下文管理器可以在代码块执行前后自动执行一些操作,如打开和关闭文件、获取和释放锁等。
代码示例
class File:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_value, traceback):
self.file.close()
with File('test.txt', 'w') as f:
f.write('Hello, world!')
十五、call
功能介绍
__call__方法使得对象可以像函数一样被调用。
代码示例
class Adder:
def __call__(self, a, b):
return a + b
adder = Adder()
result = adder(3, 5)
print(result) # 输出: 8
十六、metaclass
功能介绍
元类是创建类的类。在 Python 中,默认的元类是 type。通过自定义元类,可以在类创建时进行一些额外的操作。
代码示例
class MyMeta(type):
def __new__(cls, name, bases, attrs):
# 在类创建时添加一个额外的属性
attrs['extra_attribute'] = 'This is an extra attribute.'
return super().__new__(cls, name, bases, attrs)
class MyClass(metaclass=MyMeta):
pass
print(MyClass.extra_attribute) # 输出: This is an extra attribute.
结语
通过这个21天的Python计划,我们涵盖了面向对象高级。希望这些内容能帮助你更好地理解和使用Python。继续学习和实践,你将成为一名优秀的Python开发者!