zoukankan      html  css  js  c++  java
  • 24 Python 对象进阶

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

    1 class Foo(object):
    2      pass
    3   
    4 obj = Foo()
    5   
    6 isinstance(obj, Foo)
    View Code

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

    1 class Foo(object):
    2     pass
    3  
    4 class Bar(Foo):
    5     pass
    6  
    7 issubclass(Bar, Foo)
    View Code

    反射

    1 什么是反射

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

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

    四个可以实现自省的函数

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

     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__)
    View Code
     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')
    View Code
     1 import sys
     2 
     3 
     4 def s1():
     5     print 's1'
     6 
     7 
     8 def s2():
     9     print 's2'
    10 
    11 
    12 this_module = sys.modules[__name__]
    13 
    14 hasattr(this_module, 's1')
    15 getattr(this_module, 's2')
    View Code

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

    __str__和__repr__

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

    自定制格式化字符串__format__

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

    __del__

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

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

    1 class Foo:
    2 
    3     def __del__(self):
    4         print('执行我啦')
    5 
    6 f1=Foo()
    7 del f1
    8 print('------->')
    __del__(析构方法)

    item系列

     1 class Foo:
     2     def __init__(self,name):
     3         self.name=name
     4 
     5     def __getitem__(self, item):
     6         print(self.__dict__[item])
     7 
     8     def __setitem__(self, key, value):
     9         self.__dict__[key]=value
    10     def __delitem__(self, key):
    11         print('del obj[key]时,我执行')
    12         self.__dict__.pop(key)
    13     def __delattr__(self, item):
    14         print('del obj.key时,我执行')
    15         self.__dict__.pop(item)
    16 
    17 f1=Foo('sb')
    18 f1['age']=18
    19 f1['age1']=19
    20 del f1.age1
    21 del f1['age']
    22 f1['name']='alex'
    23 print(f1.__dict__)
    __getitem__/__setitem__/__delitem__

    __new__

    1 class Foo:
    2     def __init__(self):
    3         self.x = 1
    4         print('in init function')
    5 
    6     def __new__(cls, *args, **kwargs):
    7         print('in new function')
    8         return object.__new__(cls, *args, **kwargs)
    __new__

    __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__
    __call__

    __len__

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

    __hash__

     1 class Foo:
     2     def __init__(self):
     3         self.a = 1234
     4         self.b = 5678
     5 
     6     def __hash__(self):
     7         return hash(str(self.a) + str(self.b))
     8 
     9 f = Foo()
    10 print(hash(f))
    __hash__

    __eq__

     1 class Foo:
     2     def __init__(self):
     3         self.a = 1
     4         self.b = 2
     5 
     6     def __eq__(self, other):
     7         if self.a == other.a and self.b == other.b:
     8             return True
     9 
    10 a = Foo()
    11 b = Foo()
    12 print(a == b)
    View Code
     1 from collections import namedtuple
     2 Card = namedtuple('Card', ['rank', 'suit'])
     3 class FranchDeck:
     4     ranks = [str(n) for n in range(2,11)] + list('JQKA')
     5     suits = ['红心','方板','梅花','黑桃']
     6 
     7     def __init__(self):
     8         self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
     9                                         for suit in FranchDeck.suits]
    10 
    11     def __len__(self):
    12         return len(self._cards)
    13 
    14     def __getitem__(self, item):
    15         return self._cards[item]
    16 
    17 deck = FranchDeck()
    18 print(deck[0])
    19 from random import choice
    20 print(choice(deck))
    21 print(choice(deck))
    纸牌游戏1
     1 from collections import namedtuple
     2 Card = namedtuple('Card', ['rank', 'suit'])
     3 class FranchDeck:
     4     ranks = [str(n) for n in range(2,11)] + list('JQKA')
     5     suits = ['红心','方板','梅花','黑桃']
     6 
     7     def __init__(self):
     8         self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
     9                                         for suit in FranchDeck.suits]
    10 
    11     def __len__(self):
    12         return len(self._cards)
    13 
    14     def __getitem__(self, item):
    15         return self._cards[item]
    16 
    17     def __setitem__(self, key, value):
    18         self._cards[key] = value
    19 
    20 deck = FranchDeck()
    21 print(deck[0])
    22 from random import choice
    23 print(choice(deck))
    24 print(choice(deck))
    25 
    26 from random import shuffle
    27 shuffle(deck[:52])
    28 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 or self.sex == other.sex:
    12             return True
    13 
    14 
    15 
    16 p_lst = []
    17 for i in range(84):
    18     p_lst.append(Person('egon',i,'male'))
    19 
    20 print(p_lst)
    21 print(set(p_lst))
    对象去重
  • 相关阅读:
    达梦数据库配置信息
    linux命令收集
    达梦数据库快速学习上手教程
    linux命令收集
    关于deciaml的类型转换问题
    exjs 导出excel
    Win7 系统IIS的配置方法 及相关参数设置
    为MFC添加UAC控制 (UAC Execution Level)
    asp.net 六大内置对象(1)
    .NET Framework 的垃圾回收器管理应用程序的内存分配和释放
  • 原文地址:https://www.cnblogs.com/panfb/p/7894980.html
Copyright © 2011-2022 走看看