首页 > 编程语言 >Python进阶学习笔记-面向对象篇

Python进阶学习笔记-面向对象篇

时间:2024-06-23 14:43:41浏览次数:24  
标签:__ 进阶 Python self 面向对象 print class def name

组合

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

相关文章

  • python组合数据类型(集合)
             ......
  • python组合数据类型(列表)
              ......
  • 【Python机器学习】NMF——将NMF应用于人脸图像
    将NMF应用于之前用过的Wild数据集中的LabeledFaces。NMF的主要参数是我们想要提取的分量个数。通常来说,这个数字要小于输入特征的个数(否则的话,将每个像素作为单独的分量就可以对数据进行解释)。首先,观察分类个数如何影响NMF重建数据的好坏:importmglearn.plotsimportnumpy......
  • python基本语法
              ......
  • 《Python编程:从入门到实践》
    书籍介绍 hi,我是神虚本书是一本针对所有层次的Python读者而作的Python入门书。全书分两部分:第一部分介绍用Python编程所必须了解的基本概念,包括matplotlib、NumPy和Pygal等强大的Python库和工具介绍,以及列表、字典、if语句、类、文件与异常、代码测试等内容;第二部......
  • python---OpenCv(二),背景分离方法较有意思
    目录边界矩形旋转矩形(最小外接矩形):计算轮廓找4个点的坐标把浮点型转为Int画轮廓边界矩形--(最大外接矩形)转灰度找轮廓找顶点画矩形显示背景分离方法(这个很好玩,可以识别在动的物体)边界矩形有两种类型的边界矩形:旋转矩形(最小外接矩形):是用最小面积绘制......
  • JavaSE 面向对象程序设计进阶 继承和方法重写 2024理论与内存详解
    继承面向对象三大特征:封装继承多态封装:对象代表什么,就封装对应的数据,并提供数据对应的行为,把零散的数据变成一个整体为什么要继承两个类中重复的代码(数据和方法)太多,所以要继承extend关键字类与类之间的父子关系让一个类和另一个类建立起继承关系publicclassStude......
  • C++面向对象多级菜单向Arduino的移植
    前段时间写了一篇文章《C++面向对象语言自制多级菜单》,文中指出了可以将HeleMenu库进行移植,现已完成技术思路,特此记录。一、特性基本与上一篇文章指出的一致,只是将菜单显示和响应函数合二为一二、代码实现基本与上一篇文章指出的一致,只是考虑到右值和左值的问题,将形参改为了co......
  • 大学生毕设神器 | 二手房房源分析 二手房房源爬虫 基于Python的二手房可视化分析 基于
    ......
  • python---四则运算
    1.四则运算编写一个Python程序,生成“加减乘除”四则运算的练习,并能判断结果是否正确。程序可以选择进行哪种运算,根据输入的数据判断运算结果是否正确,最后给出正确性统计。代码:importrandomright=0count=0print("输入1为加法")print("输入2为减法")print("输入3为乘法"......