python进阶_浅谈面向对象进阶


Posted in Python onAugust 17, 2017

学了面向对象三大特性继承,多态,封装。今天我们看看面向对象的一些进阶内容,反射和一些类的内置函数。

一、isinstance和issubclass

class Foo:
 pass

class Son(Foo):
 pass

s = Son()
#判断一个对象是不是这个类的对象,传两个参数(对象,类)
print(isinstance(s,Son))
print(isinstance(s,Foo))
#type更精准
print(type(s) is Son)
print(type(s) is Foo)

#判断一个类是不是另一类的子类,传两个参数(子类,父类)
print(issubclass(Son,Foo))
print(issubclass(Son,object))
print(issubclass(Foo,object))
print(issubclass(int,object))

二、反射

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

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

四个可以实现反射的函数:hasattr,getattr,setattr,delattr

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

class Foo:
 def __init__(self):
  self.name = 'egon'
  self.age = 73

 def func(self):
  print(123)

egg = Foo()
#常用:
#hasattr
#getattr
# print(hasattr(egg,'name'))
print(getattr(egg,'name'))
if hasattr(egg,'func'): #返回bool
 Foo_func = getattr(egg,'func') #如果存在这个方法或者属性,就返回属性值或者方法的内存地址
         #如果不存在,报错,因此要配合hasattr使用
 Foo_func()
#不常用:
#setattr
# setattr(egg,'sex','属性值')
# print(egg.sex)
# def show_name(self):
#  print(self.name + ' sb')
# setattr(egg,'sh_name',show_name)
# egg.sh_name(egg)
# show_name(egg)
# egg.sh_name()

#delattr
# delattr(egg,'name')
# print(egg.name)


# print(egg.name)
# egg.func()
# print(egg.__dict__)


#反射
#可以用字符串的方式去访问对象的属性、调用对象的方法
反射举例1
class Foo:
 f = 123 #类变量
 @classmethod
 def class_method_demo(cls):
  print('class_method_demo')
 @staticmethod
 def static_method_demo():
  print('static_method_demo')
# if hasattr(Foo,'f'):
#  print(getattr(Foo,'f'))
print(hasattr(Foo,'class_method_demo'))
method = getattr(Foo,'class_method_demo')
method()
print(hasattr(Foo,'static_method_demo'))
method2 = getattr(Foo,'static_method_demo')
method2()
#类也是对象
反射举例2
import my_module
# print(hasattr(my_module,'test'))
# # func_test = getattr(my_module,'test')
# # func_test()
# getattr(my_module,'test')()
#import其他模块应用反射

from my_module import test


def demo1():
 print('demo1')

import sys
print(__name__) #'__main__'
print(sys.modules)
#'__main__': <module '__main__' from 'D:/Python代码文件存放目录/S6/day26/6反射3.py'>
module_obj =sys.modules[__name__] #sys.modules['__main__']
# module_obj : <module '__main__' from 'D:/Python代码文件存放目录/S6/day26/6反射3.py'>
print(module_obj)
print(hasattr(module_obj,'demo1'))
getattr(module_obj,'demo1')()
#在本模块中应用反射
反射举例3
#对象
#类
#模块 : 本模块和导入的模块

def register():
 print('register')

def login():
 pass

def show_shoppinglst():
 pass
#
print('注册,登录')
ret = input('欢迎,请输入您要做的操作: ')
import sys
print(sys.modules)
# my_module = sys.modules[__name__]
# if hasattr(my_module,ret):
#  getattr(my_module,ret)()
if ret == '注册':
 register()
elif ret == '登录':
 login()
elif ret == 'shopping':
 show_shoppinglst()
反射举例4
def test():
 print('test')

三、类的内置函数

1、__str__和__repr__

class Foo:
 def __init__(self,name):
  self.name = name
 def __str__(self):
  return '%s obj info in str'%self.name
 def __repr__(self):
  return 'obj info in repr'

f = Foo('egon')
# print(f)
print('%s'%f)
print('%r'%f)
print(repr(f)) # f.__repr__()
print(str(f))
#当打印一个对象的时候,如果实现了str,打印中的返回值
#当str没有被实现的时候,就会调用repr方法
#但是当你用字符串格式化的时候 %s和%r会分别去调用__str__和__repr__
#不管是在字符串格式化的时候还是在打印对象的时候,repr方法都可以作为str方法的替补
#但反之不行
#用于友好的表示对象。如果str和repr方法你只能实现一个:先实现repr

2、__del__

class Foo:
 def __del__(self):
  print('执行我啦')

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

3、item系列

__getitem__\__setitem__\__delitem__

class Foo:
 def __init__(self):
  self.name = 'egon'
  self.age = 73
  
 def __getitem__(self, item):
  return self.__dict__[item]

 def __setitem__(self, key, value):
  # print(key,value)
  self.__dict__[key] = value

 def __delitem__(self, key):
  del self.__dict__[key]
f = Foo()
print(f['name'])
print(f['age'])
f['name'] = 'alex'
# del f['name']
print(f.name)
f1 = Foo()
print(f == f1)

4、__new__

# class A:
#  def __init__(self): #有一个方法在帮你创造self
#   print('in init function')
#   self.x = 1
#
#  def __new__(cls, *args, **kwargs):
#   print('in new function')
#   return object.__new__(A, *args, **kwargs)
# a = A()
# b = A()
# c = A()
# d = A()
# print(a,b,c,d)

#单例模式
class Singleton:
 def __new__(cls, *args, **kw):
  if not hasattr(cls, '_instance'):
   cls._instance = object.__new__(cls, *args, **kw)
  return cls._instance

one = Singleton()
two = Singleton()
three = Singleton()
go = Singleton()
print(one,two)

one.name = 'alex'
print(two.name)

5、__call__

class Foo:
 def __init__(self):
  pass
 def __call__(self, *args, **kwargs):
  print('__call__')

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

6、__len__,__hash__

class Foo:
 def __len__(self):
  return len(self.__dict__)
 def __hash__(self):
  print('my hash func')
  return hash(self.name)
f = Foo()
print(len(f))
f.name = 'egon'
print(len(f))
print(hash(f))

7、__eq__

class A:
 def __init__(self):
  self.a = 1
  self.b = 2

 def __eq__(self,obj):
  if self.a == obj.a and self.b == obj.b:
   return True
a = A()
b = A()
print(a == b)

#__eq__控制着==的结果

8、内置函数实例

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 other.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))

#只要姓名和年龄相同就默认为一人去重

去重

以上这篇python进阶_浅谈面向对象进阶就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
详解Python中contextlib上下文管理模块的用法
Jun 28 Python
关于Python中浮点数精度处理的技巧总结
Aug 10 Python
Python+tkinter使用80行代码实现一个计算器实例
Jan 16 Python
python实现寻找最长回文子序列的方法
Jun 02 Python
numpy matrix和array的乘和加实例
Jun 28 Python
python 使用值来排序一个字典的方法
Nov 16 Python
django基于cors解决跨域请求问题详解
Aug 06 Python
Python实现把多维数组展开成DataFrame
Nov 30 Python
怎么快速自学python
Jun 22 Python
python 匿名函数与三元运算学习笔记
Oct 23 Python
python函数超时自动退出的实操方法
Dec 28 Python
基于tensorflow __init__、build 和call的使用小结
Feb 26 Python
Python 比较两个数组的元素的异同方法
Aug 17 #Python
python使用opencv读取图片的实例
Aug 17 #Python
CentOS下使用yum安装python-pip失败的完美解决方法
Aug 16 #Python
python3.4下django集成使用xadmin后台的方法
Aug 15 #Python
Django 如何获取前端发送的头文件详解(推荐)
Aug 15 #Python
socket + select 完成伪并发操作的实例
Aug 15 #Python
Python日期的加减等操作的示例
Aug 15 #Python
You might like
php cookie的操作实现代码(登录)
2010/12/29 PHP
php gzip压缩输出的实现方法
2013/04/27 PHP
基于preg_match_all采集后数据处理的一点心得笔记(编码转换和正则匹配)
2014/01/31 PHP
PHP正则提取不包含指定网址的图片地址的例子
2014/04/21 PHP
跨浏览器PHP下载文件名中的中文乱码问题解决方法
2015/03/05 PHP
PHP可变函数学习小结
2015/11/29 PHP
深入解析PHP的Yii框架中的缓存功能
2016/03/29 PHP
基于jquery的一个简单的脚本验证插件
2010/04/05 Javascript
jQuery学习总结之jQuery事件
2014/06/30 Javascript
javascript实现base64 md5 sha1 密码加密
2015/09/09 Javascript
javascript基于prototype实现类似OOP继承的方法
2015/12/16 Javascript
Boostrap入门准备之border box
2016/05/09 Javascript
详解Html a标签中href和onclick用法、区别、优先级别
2017/01/16 Javascript
一次记住JavaScript的6个正则表达式方法
2018/02/22 Javascript
vue-cli3 karma单元测试的实现
2019/01/18 Javascript
React+Antd+Redux实现待办事件的方法
2019/03/14 Javascript
vue.js高德地图实现热点图代码实例
2019/04/18 Javascript
jQuery实现轮播图源码
2019/10/23 jQuery
Vue 使用beforeEach实现登录状态检查功能
2019/10/31 Javascript
JavaScript this关键字指向常用情况解析
2020/09/02 Javascript
在Vue中使用Echarts可视化库的完整步骤记录
2020/11/18 Vue.js
[44:58]2018DOTA2亚洲邀请赛 4.5 淘汰赛 LGD vs Liquid 第二场
2018/04/06 DOTA
python k-近邻算法实例分享
2014/06/11 Python
Python反爬虫技术之防止IP地址被封杀的讲解
2019/01/09 Python
Python利用scapy实现ARP欺骗的方法
2019/07/23 Python
详解如何在cmd命令窗口中搭建简单的python开发环境
2019/08/29 Python
Python3直接爬取图片URL并保存示例
2019/12/18 Python
Python短信轰炸的代码
2020/03/25 Python
Python实现手绘图效果实例分享
2020/07/22 Python
详解Anaconda 的安装教程
2020/09/23 Python
python实现录音功能(可随时停止录音)
2020/10/26 Python
CSS3 实现时间轴动画
2020/11/25 HTML / CSS
优秀民警事迹材料
2014/01/29 职场文书
质检部经理岗位职责
2014/02/19 职场文书
学习方法演讲稿
2014/05/10 职场文书
中国现代文学之经典散文三篇
2019/09/18 职场文书