面向对象之组合,魔术方法

今日内容详细

组合

组合就是一个对象拥有一个属性,该属性的值是另外一个对象

class Animal(): #继承了object类  就是新式类

    def __init__(self,name,age,gender):
        self.name=name
        self.age=age
        self.gender=gender

    def eat(self):
        print(' Animal eat')

class Cat():
    def eat(self):
        print('猫吃')

a=Animal('monkey',10,'male')
c=Cat()

c=a   #c的值就是另外一个对象
c.eat()
print(c.name)
print(c.age)
print(c.gender)

'''
什么场景下使用继承?
继承一般用在:什么是什么情况 is
比如:老师是人
----------------------------------------
什么场景下使用组合?
组合一般用在:什么有什么的情况下 has
比如:老师有级别
'''

举例:
class People():
    school = 'SH'

    def __init__(self, name, age, gender, course=None):
        self.name = name
        self.age = age
        self.gender = gender
        self.course = course
        # self.course_price = course_price
        # self.course_period = course_period


class Course():
    def __init__(self, name, price, period):
        self.name = name
        self.price = price
        self.period = period


class Student(People):  # 继承了人类
    def __init__(self, name, age, gender, course=None):
        super().__init__(name, age, gender)
        if course is None:
            course = []
        self.course = course


class Teacher(People):
    def __init__(self, name, age, gender, level):
        super().__init__(name, age, gender)
        self.level = level


python = Course('Python', 10000, 10)

stu = Student('王五', 20, 'female')

stu.course.append(python.name)
stu.course.append(python.price)
stu.course.append(python.period)
print(stu.course)
# print(stu.course.price)
# print(stu.course.period)

反射

反射指的是通过字符串来操作对象的属性,涉及到四个内置函数的使用
四个内置函数:
getattr: 获取属性
setattr:设置属性
hasattr:判断是否有某个属性
delattr:删除

'''
getattr(object,attribute,default) #如果对象有属性,返回该对象的值,如果没有,返回一个default可选的值
object:要获取属性的对象
attribute:要获取的属性名
default:可选参数,在对象没有指定属性时返回的默认值

1.一般情况下在检查对象是否具有某个属性,避免引发AttributeError异常
2.在运行时根据变量的值获取对象的属性值

setattr(object,attribute,value) #
object:要获取属性的对象
attribute:要获取的属性名
value:要设置的属性值

1.动态设置对象的属性
2.在循环或根据条件来批量设置对象的属性

hasattr(object,attribute)
object:要判断属性的对象
attribute:要判断的属性名

1.在代码中动态判断对象是否具有某个属性
2.根据对象的属性进行条件判断

delattr()
object:要删除属性的对象
attribute:要删除的属性名

1.删除对象的指定属性
2.动态删除对象的属性
'''

class Student():
    school='SH'
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def fun(self):
        print('from fun')

    def index(self):
        print('from index')

stu=Student('ln',20)

res=getattr(stu,'name')  #当属性名不存在,会报错,那么可以给一个默认值,保证代码不报错
print(res)

res1=getattr(stu,'fun1',stu.index)
res1()

res=setattr(stu,'school','China') 
print(stu.school)

print((hasattr(stu,'fun'))
      
delattr(stu,'name')
print(getattr(stu,'name'))

魔术方法

str,repr,del

__str__用于表示对象的字符串表示形式,返回一个字符串
__repr__用于表示定义对象的可打印表示形式,返回一个字符串
__del__用于定义对象销毁时行为,它在对象被垃圾回收机制回收之前被调用,它可以用来执行一些对象销毁前的清理操作

class Student():
    def __init__(self,name,age):
        self.name=name
        self.age=age

    '''
    str方法:打印对象的时候,输出对象的时候会自动触发str方法
    返回值必须时字符串类型
    如果它跟repr方法同时存在,str方法的优先级更高
    '''
    '1.用在自定义对象的字符串表示形式'
    class Person:
    	def __init__(self,name,age):
        	self.name=name
        	self.age=age
    	def __str__(self):
        	return f'name={self.name},age={self.age}'
per=Person('lw',20)
print(per)
    '2.提供更有意义的字符串表示形式'
    def __str__(self):
        return 'str'

    def __repr__(self):
        return 'repr'
stu=Student('lw',20)
print(stu)
print(stu.__repr__())
repr(stu)


#1.执行资源释放或关闭操作:
class Filehandler():
    def __init__(self,filename):
        self.filename=filename
        self.file=open(filename,'w')

    def __del__(self):
        self.file.close()
handler=Filehandler('data.txt')
程序执行完毕后,对象销毁前自动调用del方法,关闭打开的文件

#2.执行清理操作以避免资源泄漏
class Databaseconnection():
    def __init__(self,config):
        self.config=config
        self.connection=self.connect()

    def __del(self):
        self.disconnect()

    def connect(self):
        #建立与数据库的连接

    def disconnect(self):
        #断开与数据库的连接
connection=Databaseconnection(config)
#当对象不再被调用时,会自动调用del方法,断开数据库连接

class A():
    def __init__(self):
        pass

class B(A):
    pass

print(issubclass(A,B)) #判断a是不是b的子类

class A():
    '''
    我是描述信息AAAA
    '''

a=A()
print(a.__doc__)  #打印秒数信息

enter,exit

__enter__:用于定义上下文时的行为,返回一个表示该上下文的对象
__exit__:用于定义退出上下文时的行为
通常情况下他俩和with语句一起使用

#1.执行资源的清理操作
class Timer():
    def __enter__(self):
        self.start_time=time.time()
        '''
        exit方法有三个默认参数:
        exc_type:异常类型
        exc_val:异常值
        exc_tb:追溯信息
        '''
    def __exit__(self,exc_type,exc_val,exc_tb):
        self.end_time=time.time()
        print(f'time:{self.end_time-self.start_time} scends')

with Timer():
    '在这里执行需要计时的代码块'
    time.sleep(1)

#2.处理异常情况
class Open:
    def __init__(self,name):
        self.name=name

    def __enter__(self):
        print('出现with语句,对象的enter被触发,有返回值赋值给as声明的变量')
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        # print(exc_type)
        # print(exc_val)
        # print(exc_tb)
        print('with 中代码快执行完毕时执行我')

with Open('a.txt') as f:
    print('----->执行代码块')
    print('------>执行代码块')
    print(f.name)
    raise AttributeError('sos') #抛出异常,主动报错
print('-'*30) #不会执行

setattr,delattr,getattr

__setattr__:这个方法是为了让对象在赋值属性时有更多的控制

__getattr__:这个方法是为了让对象在访问不存在的属性时有更多的控制。当你使用 对象名.属性名 的方式访问对象的属性时,如果属性不存在,Python 解释器会自动调用对象的 __getattr__ 方法,并将要访问的属性名作为参数传递给它

__delattr__:在删除对象的属性时自动调用,用于自定义处理属性的删除操作

class Person():
    def __setattr__(self, name, value):
        print(f"setting attribute {name} with value {value}")
        '''
        setattr方法内部中,需要使用self.__dict__[name]来设置属性值
        而不是直接使用self.name,否则会导致无限递归调用setattr方法最终溢出堆栈
        '''
        self.__dict__[name]=value

per=Person()
per.name='alice'
per.age=25

class Person:
    def __getattr__(self, item):
        print(f"getting attribute {item}")
        return None
per=Person()
print(per.name)
print(per.age)

class Person():
    def __init__(self, item):
        self.item = item

    def __delattr__(self, item):
        if item == 'item':
            print('deleting name is not allowed ')
        else:
            del self.__dict__[item]
per=Person('alice')
del per.item
print(per.item)

setitem,getitem,delitem

__setitem__:为了让对象像列表一样通过索引进行赋值操作
__getitem__:为了让对象像列表一样通过索引获取值
__delitem__:为了让对象像列表一样通过索引删除值

class Mylist:
    def __init__(self):
        self.data = []

    def __setitem__(self, index, value):
        self.data[index] = value

    def __getitem__(self, item):
        return self.data[item]

mylist = Mylist()
mylist.data=['hello','world']
mylist[0]='hi'
print(mylist.data)

class Mylist:
    def __init__(self):
        self.data = []

    def __delitem__(self, key):
        del self.data[key]

mylist = Mylist()
mylist.data=['hello','world']
del mylist[0]
print(mylist.data)

class Mylist:
    def __init__(self):
        self.data = []

    def __getitem__(self, item):
        return self.data[item]

mylist = Mylist()
mylist.data=['hello','world']
print(mylist.data[0])

call

__call__:当一个类定义了call方法后,它的实例对象就可以像函数一样被调用

class Counter():
    def __init__(self):
        self.count=0

    def __call__(self, *args, **kwargs):
        self.count+=1
        print('调用Counter实例对象')
coun=Counter()
coun()
print(coun.count)
posted @   家购诗  阅读(7)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示