• 面向对象进阶


    __getitem__,__getattr__

    __getattr__内置使用点号获取实例属性属性如 s.name,自调用__getattr__
    __setattr__设置类实例属性 如s.name='tom',自调用__setattr__
    __getitem__ 使用[]获取实例属性 如s['name'],自调用__getitem__
    __setitem__ 使用[]设置实例属性如 s['name'] = 'tom' ,自调用__setitem__
    __dict__ 为参数字典
    
    如下代码:
    
    class Student:
        def __getattr__(self, item):
            return item + ' is not exits'
    
        def __setattr__(self, key, value):
            self.__dict__[key] = value
    
        def __getitem__(self, item):
            return self.__dict__[item]
    
        def __setitem__(self, key, value):
            self.__dict__[key] = value
    
    s = Student()
    print(s.name)  # 调用__getattr__方法 输出'name is not exits'
    s.age = 1  # 调用__setattr__ 方法
    print(s.age)  # 输出 1
    print(s['age'])  # 调用 __getitem__方法 输出1
    s['name'] = 'tom'  # 调用 __setitem__ 方法
    print(s['name'])  # 调用 __getitem__ 方法 输出 'tom'

    把模块当做脚本执行 

    我们可以通过模块的全局变量__name__来查看模块名:
    当做脚本运行:
    __name__ 等于'__main__'

    当做模块导入:
    __name__= 模块名

    作用:用来控制.py文件在不同的应用场景下执行不同的逻辑
    if __name__ == '__main__':

    isinstance和issubclass

    isinstance(obj,cls)检查是否obj是否是类 cls 的对象

    class Foo(object):
         pass
      
    obj = Foo()
      
    isinstance(obj, Foo)

    issubclass(sub, super)检查sub类是否是 super 类的派生类 

    class Foo(object):
        pass
     
    class Bar(Foo):
        pass
     
    issubclass(Bar, Foo)

    反射

    1 什么是反射

    反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

    2 python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

    四个可以实现自省的函数

    下列方法适用于类和对象(一切皆对象,类本身也是一个对象)

    1 def hasattr(*args, **kwargs): # real signature unknown
    2     """
    3     Return whether the object has an attribute with the given name.
    4     
    5     This is done by calling getattr(obj, name) and catching AttributeError.
    6     """
    7     pass
    hasattr
    1 def getattr(object, name, default=None): # known special case of getattr
    2     """
    3     getattr(object, name[, default]) -> value
    4     
    5     Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
    6     When a default argument is given, it is returned when the attribute doesn't
    7     exist; without it, an exception is raised in that case.
    8     """
    9     pass
    getattr
    1 def setattr(x, y, v): # real signature unknown; restored from __doc__
    2     """
    3     Sets the named attribute on the given object to the specified value.
    4     
    5     setattr(x, 'y', v) is equivalent to ``x.y = v''
    6     """
    7     pass
    setattr
    1 def delattr(x, y): # real signature unknown; restored from __doc__
    2     """
    3     Deletes the named attribute from the given object.
    4     
    5     delattr(x, 'y') is equivalent to ``del x.y''
    6     """
    7     pass
    delattr
     1 class Foo:
     2     f = '类的静态变量'
     3     def __init__(self,name,age):
     4         self.name=name
     5         self.age=age
     6 
     7     def say_hi(self):
     8         print('hi,%s'%self.name)
     9 
    10 obj=Foo('egon',73)
    11 
    12 #检测是否含有某属性
    13 print(hasattr(obj,'name'))
    14 print(hasattr(obj,'say_hi'))
    15 
    16 #获取属性
    17 n=getattr(obj,'name')
    18 print(n)
    19 func=getattr(obj,'say_hi')
    20 func()
    21 
    22 print(getattr(obj,'aaaaaaaa','不存在啊')) #报错
    23 
    24 #设置属性
    25 setattr(obj,'sb',True)
    26 setattr(obj,'show_name',lambda self:self.name+'sb')
    27 print(obj.__dict__)
    28 print(obj.show_name(obj))
    29 
    30 #删除属性
    31 delattr(obj,'age')
    32 delattr(obj,'show_name')
    33 delattr(obj,'show_name111')#不存在,则报错
    34 
    35 print(obj.__dict__)
    四个方法的使用演示
     1 class Foo(object):
     2  
     3     staticField = "old boy"
     4  
     5     def __init__(self):
     6         self.name = 'wupeiqi'
     7  
     8     def func(self):
     9         return 'func'
    10  
    11     @staticmethod
    12     def bar():
    13         return 'bar'
    14  
    15 print getattr(Foo, 'staticField')
    16 print getattr(Foo, 'func')
    17 print getattr(Foo, 'bar')
    类也是对象
     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 
     4 import sys
     5 
     6 
     7 def s1():
     8     print 's1'
     9 
    10 
    11 def s2():
    12     print 's2'
    13 
    14 
    15 this_module = sys.modules[__name__]
    16 
    17 hasattr(this_module, 's1')
    18 getattr(this_module, 's2')
    反射当前模块成员

    导入其他模块,利用反射查找该模块是否存在某个方法

    1 #!/usr/bin/env python
    2 # -*- coding:utf-8 -*-
    3 
    4 def test():
    5     print('from the test')
    View Code
     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3  
     4 """
     5 程序目录:
     6     module_test.py
     7     index.py
     8  
     9 当前文件:
    10     index.py
    11 """
    12 
    13 import module_test as obj
    14 
    15 #obj.test()
    16 
    17 print(hasattr(obj,'test'))
    18 
    19 getattr(obj,'test')()
    View Code

    __str__和__repr__

    改变对象的字符串显示__str__,__repr__

    自定制格式化字符串__format__

     1 #_*_coding:utf-8_*_
     2 
     3 format_dict={
     4     'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
     5     'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
     6     'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
     7 }
     8 class School:
     9     def __init__(self,name,addr,type):
    10         self.name=name
    11         self.addr=addr
    12         self.type=type
    13 
    14     def __repr__(self):
    15         return 'School(%s,%s)' %(self.name,self.addr)
    16     def __str__(self):
    17         return '(%s,%s)' %(self.name,self.addr)
    18 
    19     def __format__(self, format_spec):
    20         # if format_spec
    21         if not format_spec or format_spec not in format_dict:
    22             format_spec='nat'
    23         fmt=format_dict[format_spec]
    24         return fmt.format(obj=self)
    25 
    26 s1=School('oldboy1','北京','私立')
    27 print('from repr: ',repr(s1))
    28 print('from str: ',str(s1))
    29 print(s1)
    30 
    31 '''
    32 str函数或者print函数--->obj.__str__()
    33 repr或者交互式解释器--->obj.__repr__()
    34 如果__str__没有被定义,那么就会使用__repr__来代替输出
    35 注意:这俩方法的返回值必须是字符串,否则抛出异常
    36 '''
    37 print(format(s1,'nat'))
    38 print(format(s1,'tna'))
    39 print(format(s1,'tan'))
    40 print(format(s1,'asfdasdffd'))
    View Code
     1 class B:
     2 
     3      def __str__(self):
     4          return 'str : class B'
     5 
     6      def __repr__(self):
     7          return 'repr : class B'
     8 
     9 
    10 b=B()
    11 print('%s'%b)
    12 print('%r'%b)
    %s和%r

    __del__

    析构方法,当对象在内存中被释放时,自动触发执行。

    注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

     1 class Foo:
     2 
     3     def __del__(self):
     4         print('执行我啦')
     5 
     6 f1=Foo()
     7 del f1
     8 print('------->')
     9 
    10 #输出结果
    11 执行我啦
    12 ------->
    简单示范

    item系列

    __getitem__\__setitem__\__delitem_

    class Foo:
        def __init__(self,name):
            self.name=name
    
        def __getitem__(self, item):
            print(self.__dict__[item])
    
        def __setitem__(self, key, value):
            self.__dict__[key]=value
        def __delitem__(self, key):
            print('del obj[key]时,我执行')
            self.__dict__.pop(key)
        def __delattr__(self, item):
            print('del obj.key时,我执行')
            self.__dict__.pop(item)
    
    f1=Foo('sb')
    f1['age']=18
    f1['age1']=19
    del f1.age1
    del f1['age']
    f1['name']='alex'
    print(f1.__dict__)

    __new__

     1 class A:
     2     def __init__(self):
     3         self.x = 1
     4         print('in init function')
     5     def __new__(cls, *args, **kwargs):
     6         print('in new function')
     7         return object.__new__(A, *args, **kwargs)
     8 
     9 a = A()
    10 print(a.x)
    View Code
     1 class Singleton:
     2     def __new__(cls, *args, **kw):
     3         if not hasattr(cls, '_instance'):
     4             cls._instance = object.__new__(cls, *args, **kw)
     5         return cls._instance
     6 
     7 one = Singleton()
     8 two = Singleton()
     9 
    10 two.a = 3
    11 print(one.a)
    12 # 3
    13 # one和two完全相同,可以用id(), ==, is检测
    14 print(id(one))
    15 # 29097904
    16 print(id(two))
    17 # 29097904
    18 print(one == two)
    19 # True
    20 print(one is two)
    单例模式

    __call__

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

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

     1 class Foo:
     2 
     3     def __init__(self):
     4         pass
     5     
     6     def __call__(self, *args, **kwargs):
     7 
     8         print('__call__')
     9 
    10 
    11 obj = Foo() # 执行 __init__
    12 obj()       # 执行 __call__
    View Code

    __len__

    1 class A:
    2     def __init__(self):
    3         self.a = 1
    4         self.b = 2
    5 
    6     def __len__(self):
    7         return len(self.__dict__)
    8 a = A()
    9 print(len(a))
    View Code

    __hash__

    1 class A:
    2     def __init__(self):
    3         self.a = 1
    4         self.b = 2
    5 
    6     def __hash__(self):
    7         return hash(str(self.a)+str(self.b))
    8 a = A()
    9 print(hash(a))
    View Code

    __eq__

     1 class A:
     2     def __init__(self):
     3         self.a = 1
     4         self.b = 2
     5 
     6     def __eq__(self,obj):
     7         if  self.a == obj.a and self.b == obj.b:
     8             return True
     9 a = A()
    10 b = A()
    11 print(a == b)
    View Code
     1 class FranchDeck:
     2     ranks = [str(n) for n in range(2,11)] + list('JQKA')
     3     suits = ['红心','方板','梅花','黑桃']
     4 
     5     def __init__(self):
     6         self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
     7                                         for suit in FranchDeck.suits]
     8 
     9     def __len__(self):
    10         return len(self._cards)
    11 
    12     def __getitem__(self, item):
    13         return self._cards[item]
    14 
    15 deck = FranchDeck()
    16 print(deck[0])
    17 from random import choice
    18 print(choice(deck))
    19 print(choice(deck))
    纸牌游戏
     1 class FranchDeck:
     2     ranks = [str(n) for n in range(2,11)] + list('JQKA')
     3     suits = ['红心','方板','梅花','黑桃']
     4 
     5     def __init__(self):
     6         self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
     7                                         for suit in FranchDeck.suits]
     8 
     9     def __len__(self):
    10         return len(self._cards)
    11 
    12     def __getitem__(self, item):
    13         return self._cards[item]
    14 
    15     def __setitem__(self, key, value):
    16         self._cards[key] = value
    17 
    18 deck = FranchDeck()
    19 print(deck[0])
    20 from random import choice
    21 print(choice(deck))
    22 print(choice(deck))
    23 
    24 from random import shuffle
    25 shuffle(deck)
    26 print(deck[:5])
    纸牌游戏2
     1 class Person:
     2     def __init__(self,name,age,sex):
     3         self.name = name
     4         self.age = age
     5         self.sex = sex
     6 
     7     def __hash__(self):
     8         return hash(self.name+self.sex)
     9 
    10     def __eq__(self, other):
    11         if self.name == other.name and self.sex == other.sex:return True
    12 
    13 
    14 p_lst = []
    15 for i in range(84):
    16     p_lst.append(Person('egon',i,'male'))
    17 
    18 print(p_lst)
    19 print(set(p_lst))
    一道面试题
  • 相关阅读:
    Entity Framework Code-First(10.3):Property Mappings
    Entity Framework Code-First(10.2):Entity Mappings
    Entity Framework Code-First(10.1):EntityTypeConfiguration
    Entity Framework Code-First(10):Fluent API
    Entity Framework Code-First(9.11):DataAnnotations
    Entity Framework Code-First(9.10):DataAnnotations
    Entity Framework Code-First(9.9):DataAnnotations
    Entity Framework Code-First(9.8):DataAnnotations
    Entity Framework Code-First(9.7):DataAnnotations
    JAVA-初步认识-第六章-类与对象体现
  • 原文地址:https://www.cnblogs.com/caochao-/p/8516841.html
Copyright © 2020-2023  润新知