isinstance和issubclass

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

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

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

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

反射当前模块成员

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

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3.  
  4. def test():
  5. print('from the test')
  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')()

__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'))
  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. b=B()
  10. print('%s'%b)
  11. print('%r'%b)

%s和%r

item系列

__getitem__\__setitem__\__delitem__

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

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

简单示范

__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)
  8.  
  9. a = A()
  10. print(a.x)
  1. class Singleton:
  2. def __new__(cls, *args, **kw):
  3. if not hasattr(cls, '_instance'):
  4. cls._instance = object.__new__(cls)
  5. return cls._instance
  6.  
  7. one = Singleton()
  8. two = Singleton()
  9.  
  10. two.a = 3
  11. print(one.a)
  12. #
  13. # one和two完全相同,可以用id(), ==, is检测
  14. print(id(one))
  15. #
  16. print(id(two))
  17. #
  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. obj = Foo() # 执行 __init__
  11. obj() # 执行 __call__

with和__enter__,__exit__

  1. class A:
  2. def __enter__(self):
  3. print('before')
  4.  
  5. def __exit__(self, exc_type, exc_val, exc_tb):
  6. print('after')
  7.  
  8. with A() as a:
  9. print('')

with语句

  1. class A:
  2. def __init__(self):
  3. print('init')
  4.  
  5. def __enter__(self):
  6. print('before')
  7.  
  8. def __exit__(self, exc_type, exc_val, exc_tb):
  9. print('after')
  10.  
  11. with A() as a:
  12. print('')

with语句和init

  1. class Myfile:
  2. def __init__(self,path,mode='r',encoding = 'utf-8'):
  3. self.path = path
  4. self.mode = mode
  5. self.encoding = encoding
  6.  
  7. def __enter__(self):
  8. self.f = open(self.path, mode=self.mode, encoding=self.encoding)
  9. return self.f
  10.  
  11. def __exit__(self, exc_type, exc_val, exc_tb):
  12. self.f.close()
  13.  
  14. with Myfile('file',mode='w') as f:
  15. f.write('wahaha')

with和文件操作

  1. import pickle
  2. class MyPickledump:
  3. def __init__(self,path):
  4. self.path = path
  5.  
  6. def __enter__(self):
  7. self.f = open(self.path, mode='ab')
  8. return self
  9.  
  10. def dump(self,content):
  11. pickle.dump(content,self.f)
  12.  
  13. def __exit__(self, exc_type, exc_val, exc_tb):
  14. self.f.close()
  15.  
  16. class Mypickleload:
  17. def __init__(self,path):
  18. self.path = path
  19.  
  20. def __enter__(self):
  21. self.f = open(self.path, mode='rb')
  22. return self
  23.  
  24. def __exit__(self, exc_type, exc_val, exc_tb):
  25. self.f.close()
  26.  
  27. def load(self):
  28. return pickle.load(self.f)
  29.  
  30. def loaditer(self):
  31. while True:
  32. try:
  33. yield self.load()
  34. except EOFError:
  35. break
  36.  
  37. # with MyPickledump('file') as f:
  38. # f.dump({1,2,3,4})
  39.  
  40. with Mypickleload('file') as f:
  41. for item in f.loaditer():
  42. print(item)

with和pickle

  1. import pickle
  2. class MyPickledump:
  3. def __init__(self,path):
  4. self.path = path
  5.  
  6. def __enter__(self):
  7. self.f = open(self.path, mode='ab')
  8. return self
  9.  
  10. def dump(self,content):
  11. pickle.dump(content,self.f)
  12.  
  13. def __exit__(self, exc_type, exc_val, exc_tb):
  14. self.f.close()
  15.  
  16. class Mypickleload:
  17. def __init__(self,path):
  18. self.path = path
  19.  
  20. def __enter__(self):
  21. self.f = open(self.path, mode='rb')
  22. return self
  23.  
  24. def __exit__(self, exc_type, exc_val, exc_tb):
  25. self.f.close()
  26.  
  27. def __iter__(self):
  28. while True:
  29. try:
  30. yield pickle.load(self.f)
  31. except EOFError:
  32. break
  33.  
  34. # with MyPickledump('file') as f:
  35. # f.dump({1,2,3,4})
  36.  
  37. with Mypickleload('file') as f:
  38. for item in f:
  39. print(item)

with和pickle和iter

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

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

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

  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. p_lst = []
  14. for i in range(84):
  15. p_lst.append(Person('egon',i,'male'))
  16.  
  17. print(p_lst)
  18. print(set(p_lst))

一道面试题

Python_面向对象进阶的更多相关文章

  1. python_面向对象进阶(7)

    第1章 面向对象特性—继承(补充) 1.1 接口类.抽象类介绍 1.2 接口类 1.3 接口类应用过程 1.3.1 第一版:完成多种支付方式接口 1.3.2 第二版: 归一化设计,统一支付方式 1.3 ...

  2. Python全栈开发【面向对象进阶】

    Python全栈开发[面向对象进阶] 本节内容: isinstance(obj,cls)和issubclass(sub,super) 反射 __setattr__,__delattr__,__geta ...

  3. day26、面向对象进阶:多态、封装、反射

    一.多态 什么是多态: 类的继承有两层意义:1.改变 2.扩展 多态就是类的这两层意义的一个具体的实现机. 即:调用不同类实例化的对象,下的相同的方法,实现的过程不一样 python中的标准类型就是多 ...

  4. Python开发【第七篇】:面向对象 和 python面向对象进阶篇(下)

    Python开发[第七篇]:面向对象   详见:<Python之路[第五篇]:面向对象及相关> python 面向对象(进阶篇)   上一篇<Python 面向对象(初级篇)> ...

  5. python基础——面向对象进阶下

    python基础--面向对象进阶下 1 __setitem__,__getitem,__delitem__ 把对象操作属性模拟成字典的格式 想对比__getattr__(), __setattr__( ...

  6. python基础——面向对象进阶

    python基础--面向对象进阶 1.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 ...

  7. 周末班:Python基础之面向对象进阶

    面向对象进阶 类型判断 issubclass 首先,我们先看issubclass() 这个内置函数可以帮我们判断x类是否是y类型的子类. class Base: pass class Foo(Base ...

  8. Python面向对象进阶和socket网络编程-day08

    写在前面 上课第八天,打卡: 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __i ...

  9. 铁乐学python_day24_面向对象进阶1_内置方法

    铁乐学python_day24_面向对象进阶1_内置方法 题外话1: 学习方法[wwwh] what where why how 是什么,用在哪里,为什么,怎么用 学习到一个新知识点的时候,多问问上面 ...

随机推荐

  1. CSS的一些文本操作有哪些

    一.文本的对齐方式 text-align:center/left/right text-align:justify; font-style:normal/italic/oblique/inherit ...

  2. 开发分支管理模型之阿里AoneFlow

    说到分支管理模型,令人最为熟悉的莫过于TrunkBased 和 GitFlow. TrunkBased 模型是持续集成思想所崇尚的工作方式,它由单个master分支和许多release分支组成,每个r ...

  3. Fabric智能合约(base)

    这里的智能合约仅包含Init函数和Invoke函数. 为什么一定是这两个方法? 因为在源码中的智能合约模块有这样的接口,如果要完成智能合约的相关编程,就需要实现源码中定义的接口,接口中定义了这两个方法 ...

  4. java开发相关工具安装包分享

    链接:https://pan.baidu.com/s/19rSlXhrZ9AtNdai64tErGQ 提取码:04up

  5. npm常用模块汇总

    npm常用模块汇总: 点击插件名字,查看使用文档 npm常用模块汇总 node常用模块汇总 gulp常用插件汇总 npx 使用教程:npx使用教程 bable:bable这是JavaScript编译器 ...

  6. 关于全球唯一标识GUID的生成

    1.c#生成GUID的几种方式 (1)生成标准的标志符 (36位标准) var strguid = Guid.NewGuid().ToString(); 结果:B2A5AB40-EE29-4791-9 ...

  7. (1)-Android学习笔记之:初识Android系统架构和项目结构

    Android系统架构 Android程序结构 创建一个Android项目,为初学便于理解,将程序项目结构切换为Project模式,项目结构如下 .gradle和.idea:这两个目录下放的都是And ...

  8. 关于整合ssh中的细节03

    关于spring中提供的一些工具类和监听介绍 一.spring提供了一个HibernateTemplate类 ①HibernateTemplate类: 用于操作PO对象,类似Hibernate Ses ...

  9. [CF1034B] Longest Palindrome - 贪心

    如果自己是回文串可以做中心 如果一个串和另一个串的转置相等则可以凑一对 优先配对 #include <bits/stdc++.h> using namespace std; int n,m ...

  10. Springboot 中的配置文件

    Spring Boot提供了两种常用的配置文件,分别是properties文件和yml文件.他们的作用都是修改Spring Boot自动配置的默认值. 技术:yaml.properties语法,Con ...