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

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

一、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_obj =sys.modules[__name__] #sys.modules['__main__']

# module_obj :

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进阶_浅谈面向对象进阶的更多相关文章

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

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

  2. 安卓开发_浅谈ListView(SimpleAdapter数组适配器)

    安卓开发_浅谈ListView(ArrayAdapter数组适配器) 学习使用ListView组件和SimapleAdapter适配器实现一个带图标的ListView列表 总共3部分 一.MainAc ...

  3. 安卓开发_浅谈Android动画(四)

    Property动画 概念:属性动画,即通过改变对象属性的动画. 特点:属性动画真正改变了一个UI控件,包括其事件触发焦点的位置 一.重要的动画类及属性值: 1.  ValueAnimator 基本属 ...

  4. 安卓开发_浅谈ListView(自定义适配器)

    ListView作为一个实际开发中使用率非常高的视图,一般的系统自带的适配器都无法满足开发中的需求,这时候就需要开发人员来自定义适配器使得ListView能够有一个不错的显示效果 有这样一个Demo ...

  5. Python测试开发-浅谈如何自动化生成测试脚本

    Python测试开发-浅谈如何自动化生成测试脚本 原创: fin  测试开发社区  前天 阅读文本大概需要 6.66 分钟. 一 .接口列表展示,并选择 在右边,点击选择要关联的接口,区分是否要登录, ...

  6. Web Service进阶(七)浅谈SOAP Webservice和RESTful Webservice

    浅谈SOAP Webservice和RESTful Webservice REST是一种架构风格,其核心是面向资源,REST专门针对网络应用设计和开发方式,以降低开发的复杂性,提高系统的可伸缩性.RE ...

  7. python学习(28) 浅谈可变对象的单例模式设计

    python开发,有时候需要设计单例模式保证操作的唯一性和安全性.理论上python语言底层实现和C/C++不同,python采取的是引用模式,当一个对象是可变对象,对其修改不会更改引用的指向,当一个 ...

  8. Python进阶之浅谈内置方法(补充)

    目录 列表类型的内置方法 元组类型的内置方法 字典类型的内置方法 集合类型的内置方法 列表类型的内置方法 1.作用:描述名字,说的话等 2.定义方式 s=['tim','age'] s=str('ti ...

  9. Python进阶之浅谈内置方法

    目录 有序or无序和可变or不可变 数字类型内置方法 整形 浮点型 字符串类型内置方法 有序or无序和可变or不可变 有序:有索引 无序:无索引 可变:变量值变,id不变 不可变:变量值变,id也变 ...

随机推荐

  1. C#winform datagridview单元格的单击处理

    首先看看效果图: 需求:要求是的在datagridview里面绑定数据后,可以任意点击想要点击的某列的单元格进行改变数据.需要在datagridview里面写3个事件 1.RowPrePaint事件: ...

  2. 【AT3611】Tree MST

    题目 这个题的输入首先就是一棵树,我们考虑一下点分 我们对于每一个分治重心考虑一下跨过这个分治重心的连边情况 就是把当前分治区域内所有的点向距离分治重心最近的点连边 考虑一下这个算法的正确性,如果我们 ...

  3. 面试系列16 dubbo负载均衡策略和集群容错策略都有哪些?动态代理策略呢

    (1)dubbo负载均衡策略 1)random loadbalance 默认情况下,dubbo是random load balance随机调用实现负载均衡,可以对provider不同实例设置不同的权重 ...

  4. 为什么不直接使用socket ,还要定义一个新的websocket 的呢

    大致概念: TCP/IP 协议,是网络七层协议的第四层,本身没有长连接或短连接的区别: HTTP 是基于 TCP 协议之上的「短连接」应用层协议,它的出现极大简化了网络应用的实现门槛,丰富了应用: S ...

  5. 2016.11.5初中部上午NOIP普及组比赛总结

    2016.10.29初中部上午NOIP普及组 这次比赛算是考的最差的一次之一了,当中有四分之三是DP. 进度: 比赛:没分+0+没分+40=40 改题:AC+0+没分+40=140 TurnOffLi ...

  6. 廖雪峰Java11多线程编程-3高级concurrent包-1ReentrantLock

    线程同步: 是因为多线程读写竞争资源需要同步 Java语言提供了synchronized/wait/notify来实现同步 编写多线程同步很困难 所以Java提供了java.util.concurre ...

  7. csp-s模拟测试61砖块, 数字,甜圈题解

    题面:https://www.cnblogs.com/Juve/articles/11626350.html 砖块: 直接模拟即可,map统计被覆盖的次数 #include<iostream&g ...

  8. 0903NOIP模拟测试赛后总结

    分-rank33.这次考试心态挂了. 拿到题目通读三道题,发现都十分恶心. 然后把时间押到了T1上.将近两个小时,打了个dfs,一直调调调. 最后没调出来,手模了个数据就把自己两个小时的思路hack了 ...

  9. opencv3 使用glob遍历并修改文件名

    1.函数说明 string::find()函数:是一个字符或字符串查找函数,该函数有唯一的返回类型,即string::size_type,即一个无符号整形类型,可能是整数也可能是长整数.如果查找成功, ...

  10. iOS之CGPath的应用(二)

    1.矩形路径 CG_EXTERN CGPathRef CGPathCreateWithRect(CGRect rect, const CGAffineTransform * __nullable tr ...