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 相关文章推荐
Python3 入门教程 简单但比较不错
Nov 29 Python
解决python3 urllib中urlopen报错的问题
Mar 25 Python
Python学习小技巧之列表项的拼接
May 20 Python
Python实现常见的回文字符串算法
Nov 14 Python
使用k8s部署Django项目的方法步骤
Jan 14 Python
如何在Django中设置定时任务的方法示例
Jan 18 Python
python实现AES和RSA加解密的方法
Mar 28 Python
python使用SQLAlchemy操作MySQL
Jan 02 Python
Tensorflow的常用矩阵生成方式
Jan 04 Python
Python环境使用OpenCV检测人脸实现教程
Oct 19 Python
matplotlib绘制鼠标的十字光标的实现(自定义方式,官方实例)
Jan 10 Python
python中pycryto实现数据加密
Apr 29 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
smarty+adodb+部分自定义类的php开发模式
2006/12/31 PHP
php daodb插入、更新与删除数据
2009/03/19 PHP
php正则取img标记中任意属性(正则替换去掉或改变图片img标记中的任意属性)
2013/08/13 PHP
学习PHP session的传递方式
2016/06/15 PHP
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
2018/06/16 PHP
php 多个变量指向同一个引用($b = &amp;$a)用法分析
2019/11/13 PHP
XP折叠菜单&amp;仿QQ2006菜单
2006/12/16 Javascript
JQUERY设置IFRAME的SRC值的代码
2010/11/30 Javascript
jQuery选择器的工作原理和优化分析
2011/07/25 Javascript
JS去除数组重复值的五种不同方法
2013/09/06 Javascript
JS实现字体选色板实例代码
2013/11/20 Javascript
删除节点的jquery代码
2014/01/13 Javascript
iframe子页面与父页面在同域或不同域下的js通信
2014/05/07 Javascript
jQuery和AngularJS的区别浅析
2015/01/29 Javascript
深入浅析JavaScript字符串操作方法 slice、substr、substring及其IE兼容性
2015/12/16 Javascript
获取IE浏览器Cookie信息的方法
2017/01/23 Javascript
详解angular 中的自定义指令之详解API
2017/06/20 Javascript
利用express启动一个server服务的方法
2017/09/17 Javascript
vue项目base64字符串转图片的实现代码
2018/07/13 Javascript
React实现全局组件的Toast轻提示效果
2018/09/21 Javascript
vue的三种图片引入方式代码实例
2019/11/19 Javascript
原生小程序封装跑马灯效果
2020/10/21 Javascript
[49:29]LGD vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
Python os模块中的isfile()和isdir()函数均返回false问题解决方法
2015/02/04 Python
Python检测生僻字的实现方法
2016/10/23 Python
python 出现SyntaxError: non-keyword arg after keyword arg错误解决办法
2017/02/14 Python
Python操作Sql Server 2008数据库的方法详解
2018/05/17 Python
用python生成(动态彩色)二维码的方法(使用myqr库实现)
2019/06/24 Python
naturalizer加拿大官网:美国娜然女鞋
2017/04/04 全球购物
什么是Rollback Segment
2013/04/22 面试题
消防标语大全
2014/06/07 职场文书
中学生爱国演讲稿
2014/09/05 职场文书
校园运动会广播稿
2014/10/06 职场文书
专项资金申请报告
2015/05/15 职场文书
OpenCV-Python直方图均衡化实现图像去雾
2021/06/07 Python
使用JS前端技术实现静态图片局部流动效果
2022/08/05 Javascript