组合
class Engine:
"""引擎类,提供基本的引擎功能"""
def __init__(self, power):
self.power = power
def start(self):
print(f"引擎启动,功率:{self.power}")
class Car:
"""汽车类,使用引擎类的功能"""
def __init__(self, engine, color):
self.engine = engine # 引擎组合
self.color = color
def start_car(self):
self.engine.start() # 使用引擎的start方法
# 创建一个Engine实例
engine = Engine(200)
# 创建一个Car实例,并使用Engine实例
car = Car(engine, "红色")
# 启动汽车,实际上是启动引擎
car.start_car()
绑定
class MyClass:
def __init__(self, value):
self.attribute = value
obj = MyClass(10)
print(obj.attribute) # 输出: 10
# 在类定义外部进行绑定通常是指给实例添加新的属性。
class MyClass:
pass
obj = MyClass()
obj.new_attribute = 20
print(obj.new_attribute) # 输出: 20
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'>]
多态
class Animal:
def speak(self):
raise NotImplementedError("子类必须实现该方法")
class Dog(Animal):
def speak(self):
return "汪汪汪"
class Cat(Animal):
def speak(self):
return "喵喵喵"
def animal_speaks(animal):
"""接受所有Animal类的子类实例,并调用它们的speak方法"""
print(animal.speak())
# 使用示例
dog = Dog()
cat = Cat()
animal_speaks(dog) # 输出: 汪汪汪
animal_speaks(cat) # 输出: 喵喵喵
鸭子类型
class Duck:
def quack(self):
print("Quack")
class Person:
def quack(self):
print("I am quacking like a duck!")
def perform_quack(duck):
duck.quack()
duck = Duck()
perform_quack(duck) # 输出: Quack
person = Person()
perform_quack(person) # 输出: I am quacking like a duck!
私有变量
class MyClass:
def __init__(self):
self.__private_var = 123 # 私有变量
def get_private_var(self): # 提供一个公共方法来获取私有变量的值
return self.__private_var
def update_private_var(self, value): # 提供一个公共方法来更新私有变量的值
self.__private_var = value
# 创建类的实例
obj = MyClass()
# 尝试直接访问私有变量会导致错误
# print(obj.__private_var) # 这会抛出 AttributeError
# 通过公共方法访问私有变量
print(obj.get_private_var()) # 输出: 123
# 通过公共方法更新私有变量的值
obj.update_private_var(456)
print(obj.get_private_var()) # 输出: 456
下划线
# _xx:以单下划线开头,表示这是一个保护成员,只有类对象和子类对象自己能访问到这些变量。以单下划线开头的变量和函数被默认当作是内部函数,使用from module improt *时不会被获取,但是使用import module可以获取
# __xx:双下划线开头,表示为私有成员,只允许类本身访问,子类也不行。在文本上被替换为_class__method 或者 _class__变量名
# __xx__:双下划线开头,双下划线结尾。一种约定,Python内部的名字,用来区别其他用户自定义的命名,以防冲突。是一些 Python 的“魔术”对象,表示这是一个特殊成员
# xx_:以单下划线结尾仅仅是为了区别该名称与关键词
slots属性
# Python中的__slots__是一种优化机制,它限制了类实例能够添加的属性。使用__slots__主要是为了节省内存,尤其是当你有大量实例且具有相同的属性时。继承来自父类的slots属性在子类中不生效。
class Person:
__slots__ = ['name', 'age']
def __init__(self, name, age):
self.name = name
self.age = age
# 创建实例
p = Person('Alice', 30)
p.name = 'Bob' # 允许
p.score = 100 # 会抛出AttributeError,因为没有在__slots__中定义
内省
# dir([object]):返回对象的属性列表。如果没有提供参数,则返回当前范围内的变量、方法和定义的类。
class Person:
def __init__(self, name):
self.name = name
p = Person('Alice')
print(dir(p)) # 输出对象p的属性列表
# type(object):返回对象的类型。
print(type(42)) # 输出:<class 'int'>
# hasattr(object, name):检查对象是否有指定的属性。
class Person:
def __init__(self, name):
self.name = name
p = Person('Alice')
print(hasattr(p, 'name')) # 输出:True
# getattr(object, name[, default]):返回对象指定的属性值,如果属性不存在,则返回默认值。
class Person:
def __init__(self, name):
self.name = name
p = Person('Alice')
print(getattr(p, 'name', 'default')) # 输出:'Alice'
print(getattr(p, 'age', 'default')) # 输出:'default'
# setattr(object, name, value):设置对象指定的属性值。
class Person:
def __init__(self, name):
self.name = name
p = Person('Alice')
setattr(p, 'name', 'Bob')
print(p.name) # 输出:'Bob'
# delattr(object, name):删除对象指定的属性。
class Person:
def __init__(self, name):
self.name = name
p = Person('Alice')
delattr(p, 'name')
print(p.name) # 抛出AttributeError
# isinstance(object, classinfo):检查对象是否是指定类的实例。
class Person:
pass
p = Person()
print(isinstance(p, Person)) # 输出:True
# issubclass(class, classinfo):检查类是否是指定的基类的子类。
class Person:
pass
class Student(Person):
pass
print(issubclass(Student, Person)) # 输出:True
# 模块对象主要的元数据如下表:
元数据 含义说明
__name__ 模块名
__doc__ 模块的文档注释
__file__ 源文件名(包含路径)
__dict__ 包含了模块里可用的属性名-属性的字典;也就是可以使用模块名.属性名访问的对象。
# 函数对象主要的元数据如下表:
元数据 含义说明
__name__ 函数名
__doc__ 函数的文档注释
__module__ 函数所在的模块名,如果是入口模块会被重置为__main__
__defaults__ 默认位置参数的值元组。
__kwdefaults__ 按名的默认参数的值元组
__code__ 代码对象,函数的主代码
__class__ 指向函数对象类型
# 类的元数据如下表:
元数据 含义说明
__name__ 类名
__doc__ 类的文档注释
__module__ 类所在的模块名,注意如果是入口模块,显示的是__main__模块
__bases__ 父类元组
__dict__ 类对象的所有属性信息用字典的方式表示
# 实例(也就是类的对象)元数据如下表:
元数据 含义说明
__doc__ 类的文档注释
__class__ 指向类对象
__dict__ 对象的属性,包括私有属性,注意私有属性的命名方式
# 对象方法是特殊的函数,它有函数的全部元数据,也有自己特有的元数据如下表:
元数据 含义说明
__name__ 函数名
__doc__ 函数的文档注释
__module__ 函数所在的模块名,如果是入口模块会被重置为__main__
__defaults__ 默认位置参数的值元组。
__kwdefaults__ 按名的默认参数的值元组
__code__ 代码对象,函数的主代码
__class__ 指向函数对象类型
__self__ 方法特有的属性:指向实例对象
__func__ 方法特有的属性:指向函数对象自己
魔术方法
# __init__:构造器,当创建对象时调用。
class MyClass:
def __init__(self, value):
self.value = value
obj = MyClass(10)
# __new__:用于处理对象的创建过程。它是在类的__init__方法被调用之前调用的。
class MyClass:
def __new__(cls, *args, **kwargs):
print(f"Creating instance of {cls.__name__}")
instance = super().__new__(cls) # 创建新实例
return instance
def __init__(self, value):
self.value = value
print(f"Initializing {self.__class__.__name__} with value {self.value}")
obj = MyClass(10)
# __del__:它在对象被垃圾收集之前被调用。这个方法允许在删除对象时执行自定义清理操作。
class Example:
'''
# 在这个例子中,当我们删除ex对象时,Python解释器会在垃圾收集该对象之前调用__del__方法,并输出一条消息。
# 请注意,尽管__del__方法提供了一个在对象被销毁时运行清理代码的方式,但它不应该依赖于它的执行,因为它的执行不是确定的,且可能会受到垃圾回收器的调度影响。
# 在大多数情况下,你应该使用上下文管理器(__enter__和__exit__方法)或者显式的清理方法来代替。
'''
def __init__(self, name):
self.name = name
print(f"{self.name}对象被创建")
def __del__(self):
print(f"{self.name}对象被垃圾收集器回收")
ex = Example("示例")
del ex
# __add__:定义对象的加法行为。
class MyClass:
def __init__(self, value):
self.value = value
def __add__(self, other):
return self.value + other.value
obj1 = MyClass(10)
obj2 = MyClass(20)
result = obj1 + obj2 # 输出: 30
# __len__: 当你使用len()函数时调用,用于计算对象的长度
class MyClass:
def __init__(self, values):
self.values = values
def __len__(self):
return len(self.values)
obj = MyClass([1, 2, 3, 4])
print(len(obj)) # 输出: 4
# __getattr__:当尝试访问对象不存在的属性时,会自动调用此方法。
class MyClass:
def __init__(self):
self.x = 10
def __getattr__(self, attr):
if attr == 'y':
return 20
else:
raise AttributeError("'MyClass' object has no attribute '{}'".format(attr))
obj = MyClass()
print(obj.x) # 输出:10
print(obj.y) # 输出:20
# __setattr__:当试图对对象的属性赋值时,会自动调用此方法。
class MyClass:
def __init__(self):
self.x = 10
def __setattr__(self, name, value):
print(f'Setting {name} to {value}')
self.__dict__[name] = value
obj = MyClass()
obj.x = 20 # 输出:Setting x to 20
# __delattr__:当尝试删除对象的属性时,会自动调用此方法。
class MyClass:
def __init__(self):
self.x = 10
def __delattr__(self, name):
print(f'Deleting {name}')
del self.__dict__[name]
obj = MyClass()
del obj.x # 输出:Deleting x
# __getitem__和__setitem__:设置与获取索引和切片元素
class FruitBasket:
def __init__(self):
self.fruits = {}
def __getitem__(self, item):
return self.fruits[item]
def __setitem__(self, key, value):
self.fruits[key] = value
basket = FruitBasket()
basket['apple'] = 'Apple Inc.'
print(basket['apple']) # 输出: Apple Inc.
# __iter__ 和 __next__: 用于定义对象的迭代行为
class Fibonacci:
def __init__(self, n):
self.a = 0
self.b = 1
self.n = n
def __iter__(self):
return self
def __next__(self):
if self.n <= 0:
raise StopIteration
else:
self.a, self.b = self.b, self.a + self.b
self.n -= 1
return self.a
fib = Fibonacci(10)
for num in fib:
print(num)
# __contains__:检查元素是否在容器中
class MyContainer:
def __init__(self, items):
self.items = set(items)
def __contains__(self, item):
return item in self.items
my_container = MyContainer([1, 2, 3, 4, 5])
print(1 in my_container) # 输出: True
print(6 in my_container) # 输出: False
# __bool__:当对象被布尔化时调用的魔法方
class MyBoolean:
def __init__(self, value):
self.value = value
def __bool__(self):
# 自定义当对象被布尔化时的行为
return bool(self.value)
x = MyBoolean(True)
y = MyBoolean(False)
print(bool(x)) # 输出: True
print(bool(y)) # 输出: False
# __lt__,__gt__,__eq__,__ne__,__le__,__ge__:等值比较
class MyNumber:
def __init__(self, value):
self.value = value
def __lt__(self, other):
return self.value < other.value
def __gt__(self, other):
return self.value > other.value
def __eq__(self, other):
return self.value == other.value
def __ne__(self, other):
return self.value != other.value
def __le__(self, other):
return self.value <= other.value
def __ge__(self, other):
return self.value >= other.value
a = MyNumber(10)
b = MyNumber(20)
print(a < b) # 输出: True
print(a > b) # 输出: False
print(a == b) # 输出: False
print(a != b) # 输出: True
print(a <= b) # 输出: True
print(a >= b) # 输出: False
# __call__:类的实例可以像函数一样被调用。
class Greeting:
def __init__(self, greeting):
self.greeting = greeting
def __call__(self, name):
return f"{self.greeting}, {name}!"
greet_spanish = Greeting("Hola")
print(greet_spanish("World")) # 输出: Hola, World!
# __repr__:用于定义对象的字符串表示形式
class MyClass:
def __init__(self, value):
self.value = value
def __repr__(self):
return f'MyClass({self.value!r})'
# 使用示例
obj = MyClass(42)
print(repr(obj)) # 输出: "MyClass(42)"
# __str__:当使用print()函数时调用,用于定义对象的字符串表示。
class MyClass:
def __init__(self, value):
self.value = value
def __str__(self):
return f"MyClass with value: {self.value}"
obj = MyClass(10)
print(obj) # 输出: MyClass with value: 10
property函数
class C:
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
# 使用例子
c = C()
c.x = 10
print(c.x) # 输出: 10
del c.x
try:
print(c.x)
except AttributeError as e:
print(e) # 输出: 'C' object has no attribute '_x'
类方法和静态方法
class MyClass:
'''
类方法接收类作为它的第一个参数,通常以cls作为前缀。静态方法则不接受任何特殊参数,可以看作是全局函数。 这两种方法都可以通过类直接调用,无需创建类的实例。
'''
@classmethod
def class_method(cls):
print(f"This is a class method. Class: {cls.__name__}")
@staticmethod
def static_method():
print("This is a static method.")
MyClass.class_method() # 不需要实例化
MyClass.static_method() # 同样不需要实例化
描述符协议
class MyDescriptor:
def __init__(self, name):
self.name = name
def __get__(self, instance, owner):
print(f"Getting {self.name}")
return instance.__dict__[self.name]
def __set__(self, instance, value):
print(f"Setting {self.name}")
instance.__dict__[self.name] = value
def __delete__(self, instance):
print(f"Deleting {self.name}")
instance.__dict__.pop(self.name)
class MyClass:
x = MyDescriptor('x')
obj = MyClass()
obj.x = 10 # 触发 __set__,输出 :Setting x
print(obj.x) # 触发 __get__,输出 :Getting x 10
del obj.x # 触发 __delete__,输出 :Deleting x
类装饰器
def decorator(cls):
"""
# 定义了一个装饰器函数 decorator,它接受一个类作为参数,并返回一个新的被装饰过的子类。
# 当这个装饰器被应用到 MyClass 类上时,它会创建一个新的继承自 MyClass 的内部类 DecoratedClass, # 并且在其 __init__ 方法中打印一条消息。
# 这展示了如何在不修改原始类定义的情况下,给类添加额外的初始化行为。
"""
class DecoratedClass(cls):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
print("类已被装饰器装饰。")
return DecoratedClass
@decorator # 等同于 MyClass = decorator(MyClass)
class MyClass:
def __init__(self):
print("类初始化。")
my_object = MyClass()
__init_subclass__函数
class A:
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
# 这里可以添加更多的初始化子类的代码
print(f"初始化了子类: {cls.__name__}")
# 使用 A 作为基类创建子类时,会自动调用 __init_subclass__ 方法
class B(A):
pass
# 输出: 初始化了子类: B
元类
# 给所有的子类对象增加一个作者的属性
class MetaClass(type):
def __new__(mcls, name, bases, attrs):
# 在这里,我们给类添加一个author属性
attrs["author"]= "John Doe"
return type.__new__(mcls, name, bases, attrs)
class AuthorizedClass(metaclass=MetaClass):
pass
class SubClass(AuthorizedClass):
pass
s = SubClass()
print(s.author) # 输出: John Doe
#############################################
class MetaClass(type):
def __init__(cls, name, bases, attrs):
# 在这里,我们给类添加一个author属性
cls.author= "John Doe"
return type.__init__(cls, name, bases, attrs)
class AuthorizedClass(metaclass=MetaClass):
pass
class SubClass(AuthorizedClass):
pass
s = SubClass()
print(s.author)
# 规范类名
class MetaClass(type):
def __init__(cls, name, bases, attrs):
if not name.istitle():
raise TypeError("类名称不符合规范")
return type.__init__(cls, name, bases, attrs)
class Subclass(metaclass=MetaClass): # 正常创建
pass
class SubClass(metaclass=MetaClass): # 发生异常
pass
# 只支持关键字传参
class MetaClass(type):
def __call__(cls, *args, **kwargs):
if args:
raise TypeError("只支持关键字参数")
return type.__call__(cls, *args, **kwargs)
class SubClass(metaclass=MetaClass):
def __init__(self, name):
self.name = name
s = SubClass(name="John") # 正常创建
s = SubClass("John") # 发生异常
# 类禁止被实例化
class MetaClass(type):
def __call__(cls, *args, **kwargs):
raise TypeError("该类不允许直接实例化对象")
class SubClass(metaclass=MetaClass):
pass
c = SubClass() # 发生异常
# 只允许实例化一个对象
class MetaClass(type):
def __init__(cls, name, bases, attrs):
cls.__instance = None
return type.__init__(cls, name, bases, attrs)
def __call__(cls, *args, **kwargs):
if cls.__instance is None:
cls.__instance = type.__call__(cls, *args, **kwargs)
return cls.__instance
else:
return cls.__instance
class SubClass(metaclass=MetaClass):
pass
c1 = SubClass()
c2 = SubClass()
c1 is c2 # 输出:True
print(dir(SubClass))
抽象基类
import abc
class AbstractClass(metaclass=abc.ABCMeta):
@abc.abstractmethod
def abstract_method(self):
pass
@abc.abstractmethod
def another_abstract_method(self):
pass
# 下面的代码将会抛出错误,因为ConcreteClass没有实现所有的抽象方法
# concrete_instance = AbstractClass()
class ConcreteClass(AbstractClass):
def abstract_method(self):
print('实现了abstract_method方法')
def another_abstract_method(self):
print('实现了another_abstract_method方法')
# 这样就可以正常创建实例了
concrete_instance = ConcreteClass()
标签:__,进阶,Python,self,面向对象,print,class,def,name
From: https://www.cnblogs.com/wanghongwei-dev/p/18263439