Python-类进阶

Posted wtil

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python-类进阶相关的知识,希望对你有一定的参考价值。

# 类相关的内置函数

技术图片
# 类相关的内置函数
# 1.isinstance 用于判断,对象是否是对应类型,返回True或者False 接收两个参数,(实例化的对象,类型) 如果存在继承关系也会返回True
isinstance(1,int)
# 2.issubclass 用于判断类于类之间的继承关系 例:issubclass(B,A)判断B是否继承与A 参数只能传入类
class A:pass
class B(A):pass
a = A()
b = B()
issubclass(A,A)
# == 跟 is 的区别 (== 判断值是否相等,is判断内存地址是否相同)
isinstance
技术图片
# 反射
# 用字符串数据类型的变量名来访问,这个变量的值
‘‘‘
getattr:
    使用字符串来访问变量,或者执行方法
    
    # 访问变量
        getattr(对象|类|模块,‘变量名‘)
    # 执行方法
        getattr(对象|类|模块,‘方法名‘)(参数)
    
hasattr:
    用于判断,该属性或者方法在该对象中是否存在
    hasattr(对象|类|模块,‘方法名|属性名‘)
    
setattr:
    用于修改对象属性
    
    setattr(对象|类|模块,‘属性名‘,‘新值‘)

delattr:
    用于删除对象属性
    delattr(对象|类|模块,‘属性名‘)

‘‘‘
class A:
    name = 777
    def func(self,arg):
        print(arg)
a = A()

import sys
print(sys.modules.get(__main__))
反射
技术图片
# 反射
# 用字符串数据类型的变量名来访问,这个变量的值
‘‘‘
getattr:
    使用字符串来访问变量,或者执行方法
    
    # 访问变量
        getattr(对象|类|模块,‘变量名‘)
    # 执行方法
        getattr(对象|类|模块,‘方法名‘)(参数)
    
hasattr:
    用于判断,该属性或者方法在该对象中是否存在
    hasattr(对象|类|模块,‘方法名|属性名‘)
    
setattr:
    用于修改对象属性
    
    setattr(对象|类|模块,‘属性名‘,‘新值‘)

delattr:
    用于删除对象属性
    delattr(对象|类|模块,‘属性名‘)

‘‘‘
class A:
    name = 777
    def func(self,arg):
        print(arg)
a = A()

import sys
print(sys.modules.get(__main__))
反射简单应用

# 类中的内置方法 (特殊方法,双下方法,魔术方法)

技术图片
# __call__ 实例化对象加() 就会调用 __call__ 方法
class A:
    def __call__(self,*args,**kwargs):
        print(args:,args)
        print(kwargs:,kwargs)
        print(A 的__call__方法被调用了)
# 第一种使用方法
# a = A()
# a()

class B:
    def __init__(self,cls):
        self.a = cls()
        self.a()
# 第二种使用方法
# b = B(A)
# __call__ 实例化对象加() 就会调用 __call__ 方法
技术图片
# __len__ 在执行内置函数len()的时候回调用这个方法,该方法必须返回一个整数类型,否者会报错
# __len__ return 的值就是len()函数计算出的长度
class MyObj:
    def __init__(self,*args):
        self.args =args
    def __len__(self):
        print(MyObj的__len__方法被调用了)
        
        return 1       
obj = MyObj()
print(len(obj))

# 练习
class MyStr:
    def __init__(self,args):
        self.string = args
    def __len__(self):
        return len(self.string)
s = MyStr(asc)
print(len(s))
# __len__ 在执行内置函数len()的时候回调用这个方法,该方法必须返回一个整数类型,否者会报错
技术图片
# __new__ 构造方法,在类名+()的时候调用,然后会开辟一块内存。返回给__init__(初始化方法)中的self
class A:
    def __new__(cls,*args,**kwargs):
        # 由于Python语言无法开辟空间,我们得调用父类(object)的__new__方法来开辟空间(下面两种方法都可以)
        # obj = object.__new__(cls)
        obj = super().__new__(cls)
        print(obj)
        return obj
    
    def __init__(self):
        print(在初始化方法中,self)
              
A()
# 使用场景  单例类
class B:
    __ISINCTANCE = None
    def __new__(cls,*args,**kwargs):
        if not cls.__ISINCTANCE:
            cls.__ISINCTANCE = super().__new__(cls)
        return cls.__ISINCTANCE
    
    def __init__(self,name):
        print(self)
        self.name = name
        
a = B(1)
b = B(2) 
c = B(3)
print(a,b,c)
print(a.name,b.name,c.name)
# __new__ 构造方法,在类名+()的时候调用,然后会开辟一块内存。返回给__init__(初始化方法)中的self
技术图片
# __str__ 在执行print|str|‘%s‘% obj 的时候 调用
class A:
    def __init__(self,name):
        self.name = name
    
    def __str__(self):
        return self.name
    
a = A(444)
print(a)
print(str(a))
print(字符串格式化:%s%a)
# __str__ 在执行print|str|‘%s‘% obj 的时候 调用
技术图片
# __repr__
# 内置函数 repr()       原样输出,在打印输出的时候,原样显示\n \t等特殊字符,输出的字符串也会被""包括(但是%s占位符还是可以正常使用)
# 如果没有__str__,那么调用 __str__方法的操作会找__repr__方法来取值
class A:
    def __init__(self,name):
        self.name = name
#     def __str__(self):
#         return self.name
    def __repr__(self):
        return \‘%s\‘%self.name

class B(A):
    def __repr__(self):
        return \‘%s\‘%self.name
    

a = B(aaa)
print(a)
  
print(repr(a))
# __repr__
技术图片
# __del__  析构方法 释放一个空间
# 跟构造方法相反 __new__ 构造方法 申请一个空间
class A:
    def __del__(self,*args,**kwargs):
        ‘‘‘
        执行 del key 的时候触发
        就算这里没有写 del相关语法,照样可以删除元素
        ‘‘‘
        print(被删除了...)
        
        
        
a = A()
import time
time.sleep(10)
# __del__ 析构方法 释放一个空间
技术图片
# item 系列
# __getitem__ 、__setitem__

class B:
    def __getitem__(self,item):
        ‘‘‘
        b = B()
        在执行 b[‘key‘] 的时候调用此方法 item 会接收到key
        ‘‘‘
        return getattr(self,item)
    def __setitem__(self,key,value):
        ‘‘‘
        b = B()
        在执行 b[‘key‘]=123 的时候调用此方法 key 会接收到key ,value会接收到123
        ‘‘‘
        setattr(self,key,value)
        
    def __delitem__(self,key):
        
        ‘‘‘
        b = B()
        在执行 del b[‘key‘]的时候调用此方法 key 会接收到key 
        ‘‘‘
        delattr(self,key)

        

b = B()
b[a123] = 666
b[a123]
del b[a123]
b[a123]
# item 系列
技术图片
# 面试题 __hash__、__eq__
‘‘‘
员工管理系统类
    属性 姓名,性别,年龄,部门
    
存在重复员工信息,但是部门不同(如果存在姓名相同,性别相同。我就认为这是同一个人)
有1000的员工对象,筛选出重复的员工

‘‘‘
class Staff:

    def __init__(self,name,sex,age,department):

        self.name = name
        self.sex = sex
        self.age = age
        self.department = department
        
    def __hash__(self):
        # 自定义类的hash条件
        return hash(%s%s%(self.name,self.age))
        
    def __eq__(self,other):
        # 如果hash值相同,会触发这个方法,来判断值是否相同(True相同,False不同)
        if self.name == other.name and self.sex == other.sex:
            return True

s1 = Staff(张三,,28,运营)
s2 = Staff(李四,,28,人事)
s3 = Staff(王五,,28,财务)
s4 = Staff(钱六,,78,销售)
s5 = Staff(王五,,28,销售)
staff_list =[s1,s2,s3,s4,s5]

‘‘‘
# 使用集合的去重机制 

1.计算hash值(调用对象的__hash__方法)

    1.1 如果hash值不同,则存入hash对应的内存地址
    
    1.2 如果hash相同:判断值是否相同(调用对象的__eq__方法)
        
        1.2.1 如果值相同 :则存入hash对应的内存地址,替换之前的值
        1.2.3 如果值不同 :使用另外hash算法,进行二次寻址

最后留下来的就是不相同的
        
‘‘‘
staff_set = set(staff_list)
print(staff_set)
# 面试题 __hash__、__eq__

 

以上是关于Python-类进阶的主要内容,如果未能解决你的问题,请参考以下文章

1.26 Python知识进阶 - 继承

Python面向对象进阶及类成员

面向对象进阶

python进阶详解元类及其应用1

01月11日 四周四次Python基础进阶

Python之路,Day8 - 面向对象编程进阶