zoukankan      html  css  js  c++  java
  • 面向对象的进阶

    一、isinstance

    isinstance(o,t)检查o是不是t的对象,返回值为bool.

    class A:
        pass
    a=A()
    print(isinstance(a,A))   #True
    #a是A的对象

    二、issubclass

    issubclass(cls,classinfo) 检查B是不是继承了A,A是B的父类。

    class A:pass
    class B(A):pass
    print(issubclass(B,A))  #True    A是B的父类
    print(issubclass(A,B))   #False  B不是A的父类

    三、反射

    反射 :是用字符串类型的名字去操作变量。(python中的一切事物都是对象(都可以使用反射)

    反射对象中的属性和方法  hasattr  getattr  setattr  delattr

    1、getattr

     1 class A:
     2     def func(self):
     3         print("in func")
     4 a=A()     #实例化
     5 a.name="yaya"
     6 a.age=22
     7 
     8 #反射对象的属性
     9 ret=print(getattr(a,"name"))    #通过变量名的字符串形式取到的值
    10 print(ret)
    11 print(a.__dict__)    #{'name': 'yaya', 'age': 22}
    12 变量名=input(">>>")
    13 print(a)      #<__main__.A object at 0x000000CE0F5F6048>
    14 print(getattr(a,变量名))
    15 print(a.__dict__[变量名])
    16 
    17 #反射对象的方法
    18 a.func()      #in func
    19 ret=getattr(a,"func")
    20 ret()       #in func      调用ret方法
    21 print(ret)    #<bound method A.func of <__main__.A object at 0x000000CF18D71D68>>
    getattr

    2、hasattr

     1 #hasattr   与getattr配套使用,夫妻档
     2 class A:
     3     price=20
     4     @classmethod
     5     def func(cls):
     6         print("in func")
     7 #反射类的属性
     8 # print(getattr(A,"price"))
     9 
    10 #反射类的方法
    11 if hasattr(A,"func"):
    12     getattr(A,"func")()    #in func    直接加括号调用
    hasattr

    3、setattr 设置修改变量

    1 class A:
    2     pass
    3 a=A()
    4 setattr(a,"name","yaya")
    5 setattr(A,"name","alex")
    6 print(a.name)   #yaya
    7 print(A.name)   #alex
    setattr

    4、delattr 删除一个变量

    class A:
        pass
    a=A()
    setattr(a,"name","yaya")
    setattr(A,"name","alex")
    delattr(a,"name")
    print(a.name)
    delattr(A,"name")
    delattr

    5、其他模块

    import my
    #反射模块的属性
    print(my.day)    #Monday
    print(getattr(my,"day"))  #Monday
    #反射模块的方法
    print(getattr(my,"func"))   #<function func at 0x00000050F9D80488>
    getattr(my,"func")()    #in func   加括号直接调用
    
    ##************************************************************************************
    #内置模块也能用
    import time
    print(getattr(time,"time"))   #<built-in function time>
    print(getattr(time,"time")())  #1516609758.551611
    print(getattr(time,"asctime"))  #<built-in function asctime>
    print(getattr(time,"asctime")())  #Mon Jan 22 16:29:18 2018
    
    #************************************************************************************
    
    def func():
        print("in func")
    year=2018
    import sys
    print(sys.modules['__main__'].year)   #2018
    # 反射自己模块中的变量
    print(getattr(sys.modules["__main__"],"year"))  #2018
    
    #反射自己模块中的函数
    getattr(sys.modules["__main__"],"func")()   #in func
    变量名=input(">>>")
    print(getattr(sys.modules[__name__],变量名))
    
    #要反射的函数有参数怎么办?
    import time
    print(time.strftime("%Y-%m-%d %H:%M:%S"))   #2018-01-22 18:58:07
    print(getattr(time,"strftime")("%Y-%m-%d %H:%M:%S"))   #2018-01-22 18:58:07
    
    #一个模块中的类能不能反射得到
    import my
    print(getattr(my,"C")())  #<my.C object at 0x000000088EFFB978>
    if hasattr(my,"name"):
        getattr(my,"name")
    模块

    四、__str__   __repr__

    obj.__str__  str(obj)
    obj.__repr__ repr(obj)
     1 class Teacher:
     2     def __init__(self,name,salary):
     3         self.name = name
     4         self.salary = salary
     5     def __str__(self):
     6         return "Teacher's object :%s"%self.name
     7     def __repr__(self):
     8         return str(self.__dict__)
     9     def func(self):
    10         return 'wahaha'
    11 nezha = Teacher('哪吒',250)
    12 print(nezha)  # 打印一个对象的时候,就是调用a.__str__
    13 #Teacher's object :哪吒
    14 print(repr(nezha))     #字典形式存在
    15 #{'salary': 250, 'name': '哪吒'}
    16 print('>>> %r'%nezha)
    17 #>>> {'salary': 250, 'name': '哪吒'}
    str/repr

    补充:

    1、object 里有一个__str__,一旦被调用,就返回调用这个方法的对象的内存地址。

    2、%s str() 直接打印 实际上都是走的__str__

          %r repr() 实际上都是走的__repr__

    3、repr 是str的备胎,但str不能做repr的备胎

    4、print(obj)/'%s'%obj/str(obj)的时候,实际上是内部调用了obj.__str__方法,如果str方法有,那么他返回的必定是一个字符串。

    5、obiect为基类时,如果没有__str__方法,会先找本类中的__repr__方法,再没有再找父类中的__str__,然后是父类的__repr__。

    6、自定义父类时,先找自己的__str__,如果没有,就找父类的__str__,没有再找自己的__repr__,还没有就找父类的__repr__。

    7、repr(),只会找__repr__,如果没有找父类的。

    五、__len__

    class Classes:
        def __init__(self,name):
            self.name = name
            self.student = []
        def __len__(self):
            return len(self.student)
        def __str__(self):
            return 'classes'
    py_s9= Classes('python')
    py_s9.student.append('二哥')
    py_s9.student.append('大哥')
    print(len(py_s9))   #2
    print(py_s9)       #classes
    len

    六、__del__  析构函数

    class Foo:
    
        def __del__(self):
            print('执行我啦')
    
    f1=Foo()
    del f1
    print('------->')
    
    #输出结果
    执行我啦
    del

    七、__call__

    对象后面加括号,触发执行。

    注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()().

    class Foo:
    
        def __init__(self):
            pass
        
        def __call__(self, *args, **kwargs):
    
            print('__call__')
    
    
    obj = Foo() # 执行 __init__
    obj()       # 执行 __call__
    call

     八、item系列

    __getitem__:实例传一个参数,传到它这里,返回值,返回什么值自己可以定义。

    __setitem__:为类设置或者赋值,增长情况下应该是对__dict__增加属性值,(也可以设置成其他的乱七八糟的),主要是在对对象进行字典操作的时候会调用这个内置函数。

    __delitem__:执行字典类似的删除的操作的时候,会默认执行的内置函数(如果不想让他有它应该有的作用的时候,也可以设置成别的)

    class Foo:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        def __getitem__(self, item):
            if hasattr(self,item):
                return self.__dict__[item]
    
        def __setitem__(self, key, value):
            self.__dict__[key] = value
    
        def __delitem__(self, key):
            del self.__dict__[key]
    
    f = Foo('yaya',22,'')
    print(f['name'])         #yaya
    f['hobby'] = '帅哥'
    print(f.hobby,f['hobby'])      #帅哥 帅哥
    # del f.hobby      # object 原生支持  __delattr__
    # del f['hobby']   # 通过自己实现的
    print(f.__dict__)             #{'name': 'yaya', 'sex': '女', 'hobby': '帅哥', 'age': 22}
    item

    九、__new__

    构造方法 : 创建一个对象

    class A:
        def __init__(self):
            self.x = 1
            print('in init function')
        def __new__(cls, *args, **kwargs):
            print('in new function')
            return object.__new__(A, *args, **kwargs)
    
    a1 = A()      #in new function
                   #in init function
    a2 = A()
    a3 = A()
    print(a1)      #<__main__.A object at 0x000000FDFE5A0C50>
    print(a2)
    print(a3)
    new
    单例模式
    一个类 始终 只有 一个 实例
    当你第一次实例化这个类的时候 就创建一个实例化的对象
    当你之后再来实例化的时候 就用之前创建的对象
    class A:
        __instance = False
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __new__(cls, *args, **kwargs):
            if cls.__instance:
                return cls.__instance
            cls.__instance = object.__new__(cls)
            return cls.__instance
    
    yaya = A('yaya',22)
    yaya.cloth = '小花袄'
    alex = A('alex',28)
    print(yaya)      #<__main__.A object at 0x000000DFFFEF0E10>
    print(alex)      #<__main__.A object at 0x000000DFFFEF0E10>
    print(yaya.name)   #alex
    print(alex.name)   #alex
    print(yaya.cloth)   #小花袄
    单例模式

    十、__eq__

    class A:
        def __init__(self,name):
            self.name = name
    
        def __eq__(self, other):
            if self.__dict__ == other.__dict__:
                return True
            else:
                return False
    
    ob1 = A('egon')
    ob2 = A('egg')
    print(ob1 == ob2)   #False
    eq

    十一、__hash_

    class A:
        def __init__(self,name,sex):
            self.name = name
            self.sex = sex
        def __hash__(self):
            return hash(self.name+self.sex)
    
    a = A('yaya','')
    b = A('yaya','')
    print(hash(a))    #5854354249374934794
    print(hash(b))   #-8349671480864591817
    hash
    class FranchDeck:
        ranks = [str(n) for n in range(2,11)] + list('JQKA')
        suits = ['红心','方板','梅花','黑桃']
    
        def __init__(self):
            self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
                                            for suit in FranchDeck.suits]
    
        def __len__(self):
            return len(self._cards)
    
        def __getitem__(self, item):
            return self._cards[item]
    
    deck = FranchDeck()
    print(deck[0])
    from random import choice
    print(choice(deck))
    print(choice(deck))
    纸牌游戏
    class FranchDeck:
        ranks = [str(n) for n in range(2,11)] + list('JQKA')
        suits = ['红心','方板','梅花','黑桃']
    
        def __init__(self):
            self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
                                            for suit in FranchDeck.suits]
    
        def __len__(self):
            return len(self._cards)
    
        def __getitem__(self, item):
            return self._cards[item]
    
        def __setitem__(self, key, value):
            self._cards[key] = value
    
    deck = FranchDeck()
    print(deck[0])
    from random import choice
    print(choice(deck))
    print(choice(deck))
    
    from random import shuffle
    shuffle(deck)
    print(deck[:5])
    纸牌游戏2
    #名字和性别相同,年龄不同,去重
    class Person:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        def __hash__(self):
            return hash(self.name+self.sex)
    
        def __eq__(self, other):
            if self.name == other.name and self.sex == other.sex:return True
    
    
    p_lst = []
    for i in range(84):
        p_lst.append(Person('egon',i,'male'))
    
    print(p_lst)
    print(set(p_lst))
    面试题
  • 相关阅读:
    C#实现汉字转换为拼音缩写的代码
    C# 使用xsd文件验证XML 格式是否正确
    C#用天气预报的WebServices
    c# socket通信较完善方案
    C#操作MySQL数据库-----HelloWorld
    c# 自己制作一个简单的项目倒计时器
    C# 制作外挂常用的API
    C#中如何计算时间差?
    C# 图片保存到数据库和从数据库读取图片并显示
    c#加密 可逆与不可逆MD5 加密
  • 原文地址:https://www.cnblogs.com/gaoya666/p/8331111.html
Copyright © 2011-2022 走看看