组合,反射,魔术方法,异常

目录

组合

反射(通过字符串来操作属性)

     getattr

     setattr

     hasattr

     delattr

魔术方法(内置方法,双下划开头的方法)


组合

它不是一个新的技术栈,它是对象的另外一种用法

 

什么是组合?

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

class Foo():
    def __init__(self,m):
        self.m = m

class Bar():
    def __init__(self,n)
        self.n = n

"""一个对象拥有一个属性,该属性的值是另外一个对象"""
obj = Bar(10)
obj1 = Foo(20)
# 超级对象,通过一个属性可以访问到另一个对象的值
obj.x = obj1

print(obj.x.m)

什么情况下使用继承?什么情况下使用组合?

        继承一般情况用在:什么是什么的情况  is

        组合一般用在:什么有什么的情况  has

反射

在python中,反射指的是通过字符串来操作对象的属性,涉及到四个内置函数的使用(python中一切皆对象,类和对象都可以用下述四个方法)

 

四个内置函数:

        getattr:获取属性        # 用的最多

        setattr:设置属性

        hasattr:判断是否有某个属性

        delattr:删除

class Student():
    school = 'SH'

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

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

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

stu = Student('kevin',20)

# attr = input('请输入你要操作的属性名:')
# print(stu.school)
# print(stu."school")
"""反射:就是通过字符串的形式来操作对象的属性"""
# 1.获取属性
"""当你查询的属性不存在的时候,如果给了第三个参数,就返回第三个参数"""
# res = getattr(stu,'school1',666)

"""如果你给了第三个参数,查询的属性也存在,那就直接返回属性对应的值,默认值就没用了"""
# res=getattr(stu,'school',666)
# res1=getattr(stu,'name')
# res1=getattr(stu,'name')
# print(res,res1,res2)
# print(res)


# 函数的用法
"""必须掌握"""
res=getattr(stu,'func1',stu.index)    #  用的是最多的
print(res)
res()



#  setattr设置
# setattr(stu,'x',666)    # stu.x = 666
# print(stu.__dict__)

#  hasattr
print(hasattr(stu,'func'))
if hasattr(stu,'func')
    getattr(stu,'func')()
else:
    pass


# delattr
# delattr(stu,'name')
# del stu.name
# print(stu.__dict)

# import time
# time=__import__('time')    # import time
# print(time.time())

random = __import__('random')
print(random.randint(0,8))

内置方法之魔术方式(重要)

它的特点就是双下划线的方法,他满足一定的条件就会自动触发,简称魔法

 

面向对象中有哪些魔术方法?怎么使用?

只学10个魔术方法,不止有10个魔术方法

1. __init__

2. __str__,__repr__

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

    def __str__(self):    # 这个用的是最多的
        print('str')
        return 'from str'

    def __repr__(self):
        print('repr')
        return 'from repr'

stu = Student('ly',20)
# print(stu)
# print('repr:',repr(stu))
print('str:',stu(stu))


'''
    1. 打印对象的时候,输出对象的时候会自动触发类中得__str__方法
    2. 返回值必须是字符串形式
    3. 如果它跟__repr__方法同时存在,__str__的优先级更高
'''

3. __del__

class Mysql():
    def __init__(self,ip,port):
        self.ip = ip
        self.port = port
        self.f = open('a.txt','w')

    def __del__(self):
        print('from _del')
        self.f.close()

mysql = MySQL('127.0.0.1',3306)

print('12')
print(isinstance(123,str))
print(type(12) is int)
class Foo():
    pass
class Bar(foo):
    pass
class Bar1():
    pass

print(issubclass(Bar1,Foo))

class Foo():
'''
我是描述信息
我是描述信息
我是描述信息
'''
    pass
class Bar(foo):
    pass
print(Bar.__doc__)

4. __enter__和__exit__

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('with中代码块执行完毕是执行我啊')

"""with它可以用在很多地方,但是,出现with语句后面的对象中的类必须要声明__enter__和__exit__"""

with open('a.txt') as f:
    print('执行代码块')

    # print(f,f.name)


class Open():
    def __init__(self,name):
        self.name = name

    def __enter__(self):
        print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')

    def __exit__(self,exc_type,exc_val,exc_tb):
        print('with 中代码块执行完毕时执行我啊')
        print(exc_type)    # 异常类型
        print(exc_val)    # 异常值
        print(exc_tb)    # 追溯信息
        return True    # 如果在这个方法里面返回了True,with代码块中出现了异常,就相当于没有出现异常
    
    """with它可以用在很多地方,但是,出现with语句后面的对象中的类必须要声明__enter__和__exit__



"""如果with代码块中出现了异常,则with语句之后的代码都不能正常执行"""

with Open('a.txt') as f:
    print('执行代码块')
    raise Attribute('***着火了,救火啊***')    # 抛出异常,主动报错

print('0'*100)    # 不会执行

5. __setattr__,__delattr__,__getattr__

class Foo():
    x = 1
   
    def __init__(self,y):
        self.y = y

    """当你找的属性不存在时,会触发__getattr__,但是必须是点语法的时候才会"""
    def __getattr__(self,item):
        print('from getattr:你找的属性不存在')

    def __setattr__(self,key,value):
        print('from setattr')

        # self.key = value    # self.a=20
        # self.key = value     # 这就无限递归了,你好好想想

        self.__dict__pop(item)

obj=Foo(10)
# obj.z
obj.a=20
print(obj.a)

del obj.a

6. __setitem__,__getitem__,__delitem__

class Foo():
    def __init__(self,name):
        self.name = name

    """当你通过中括号获取对象的属性的时候,会自动触发__getitem__"""

    def __getitem__(self,item):
        print('__getitem__')
        print(self.__dict__[item])

    def __setitem__(self,key,value):
        # key:age
        # value:18
        print('__setitem__')
        self.__dict__[key] = value
        # self.__dict__['age'] = 18

    def __delitem__(self,key):
        print('del obj[key]时,我执行')
        self.__dict__.pop(key)
        pass


    # def __delattr__(self,item):
    #     print('del obj.key时,我执行')
    #     self.__dict__.pop(item)

obj=Foo('tom')
# print(obj.name)

# obj['name']
obj['age'] = 18
# obj.age = 18
print(obj.age)

del obj['age']

7. call

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

    # 当对象加括号的时候会触发__call__的执行
    
    def __call__(self,*args,**kwargs):
        print('__call__')


obj = Foo()
print(obj)
obj()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值