面向对象的知识点补充(进阶版)

classmethod和staticmethod:这两个函数的用途就是可以不用实例化对象就可以调用方法

class Classmethod_Demo():
role = 'dog' @classmethod
def func(cls):
print(cls.role) Classmethod_Demo.func() class Staticmethod_Demo():
role = 'dog' @staticmethod
def func():
print("当普通方法用") Staticmethod_Demo.func()

isinstance和issubclass

  isinstance是用来检查实例化的对象是否是由想检查的类实例化出来的,返回的是布尔值。isinstance(obj,t)

class Fruit:
def __init__(self,name):
self.name=name class Vegetable:
def __init__(self,name):
self.name=name b=Fruit('banana')
print(isinstance(b,Fruit))#True
print(isinstance(b,Vegetable))#False

  issubclass是用来检查一个类是否是想检查的类的子类,返回的是布尔值。issubclass(cls,classinfo)

class Plant:
def __init__(self,name):
self.name=name class Fruit(Plant):
def __init__(self,name):
self.name=name class Vegetable:
def __init__(self,name):
self.name=name print(issubclass(Fruit,Plant))#True
print(issubclass(Fruit,Vegetable))#False

反射

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

四个可以实现自省的函数:hasattr,getattr,setattr,delattr(后面两个不常用,平时不推荐使用)

上述四个函数适用于类和对象(一切皆对象,类本身也是一个对象)

下面用代码来提现每个函数的作用:

class Sport:
def __init__(self,name,place):
self.name=name
self.place=place
def play(self):
print('i like %s'%self.name)
def where(self):
print('we play at %s'%self.place) bas=Sport('basketball','ground')
#hasattr#查看属性,返回布尔值
print(hasattr(bas,'name'))#检测是否有属性,输出布尔值 #getattr#得到属性,可以调用方法
print(getattr(bas,'where'))#检测是否有属性,输出的是方法的内存地址
n=getattr(bas,'where')
print(n)#检测是否有属性,与上面一个print里的内容一模一样,输出的是方法的内存地址
func=getattr(bas,'where')
func()#调用方法,输出为we play at ground
# print(getattr(bas,'price'))#不存在即报错
print(getattr(bas,'price','不存在啊'))#设置默认值即不报错,输出默认值 #setattr可以更改属性,不推荐使用
setattr(bas,'price',100)#新设置一个属性
print(bas.price)
setattr(bas,'show_name',lambda self:self.name+' good')
print(bas.show_name(bas))#basketball good #delattr#删除属性,不推荐使用
delattr(bas,'place')
# delattr(bas,'name111')#不存在,则报错
print(bas.__dict__)

类也是对象,自然也可以使用上述函数:

class Foo(object):

    staticField = "old boy"

    def __init__(self):
self.name = 'alex' def func(self):
return 'func' @staticmethod
def bar():
return 'bar' print getattr(Foo, 'staticField')
print getattr(Foo, 'func')
print getattr(Foo, 'bar')

也可以用来反射当前模块成员:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import sys
def s1():
print 's1'
def s2():
print 's2' this_module = sys.modules[__name__]
hasattr(this_module, 's1')
getattr(this_module, 's2')

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

#文件一
#!/usr/bin/env python
# -*- coding:utf-8 -*- def test():
print('from the test') #文件二
#!/usr/bin/env python
# -*- coding:utf-8 -*- """
程序目录:
module_test.py
index.py 当前文件:
index.py
""" import module_test as obj #obj.test() print(hasattr(obj,'test')) getattr(obj,'test')()

以下内容供进阶了解

__str__、__repr__、__format__、__del__、__call__、__len__、__hash__、__eq__、__item__系列

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

自定制格式化字符串__format__

#_*_coding:utf-8_*_

format_dict={
'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
}
class School:
def __init__(self,name,addr,type):
self.name=name
self.addr=addr
self.type=type def __repr__(self):
return 'School(%s,%s)' %(self.name,self.addr)
def __str__(self):
return '(%s,%s)' %(self.name,self.addr) def __format__(self, format_spec):
# if format_spec
if not format_spec or format_spec not in format_dict:
format_spec='nat'
fmt=format_dict[format_spec]
return fmt.format(obj=self) s1=School('oldboy1','北京','私立')
print('from repr: ',repr(s1))#from repr: School(oldboy1,北京)
print('from str: ',str(s1))#from str: (oldboy1,北京)
print(s1)#(oldboy1,北京) '''
str函数或者print函数--->obj.__str__()
repr或者交互式解释器--->obj.__repr__()
如果__str__没有被定义,那么就会使用__repr__来代替输出
注意:这俩方法的返回值必须是字符串,否则抛出异常
'''
print(format(s1,'nat'))#oldboy1-北京-私立
print(format(s1,'tna'))#私立:oldboy1:北京
print(format(s1,'tan'))#私立/北京/oldboy1
print(format(s1,'asfdasdffd'))#oldboy1-北京-私立
class B:
def __str__(self):
return 'str : class B' def __repr__(self):
return 'repr : class B' b=B()
print('%s'%b)#repr : class B
print('%r'%b)#str : class B

__del__

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

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

class Foo:
def __del__(self):
print('执行我啦')
f1=Foo()
del f1
print('------->') #输出结果
执行我啦
------->

__call__

对象后面加括号,触发执行。

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

class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print('__call__') obj = Foo() # 执行 __init__
obj() # 执行 __call__

__len__

相当于内置的len()方法,纯粹检查长度

class A:
def __init__(self):
self.a = 1
self.b ='b' def __len__(self):
return len(self.__dict__)
a = A()
print(len(a))#2 其实电泳len方法的时候就是python在内部实现了__len__

__hash__

查看是否可以hash

class A:
def __init__(self):
self.a = 1
self.b = 2 def __hash__(self):
return hash(str(self.a)+str(self.b))
a = A()
print(hash(a))#其实调用hash方法的时候就是内部实现了__hash__

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

__item__系列:__getitem__、__setitem__、__delitem__

class Foo:
def __init__(self,name):
self.name=name def __getitem__(self, item):
print(self.__dict__[item]) def __setitem__(self, key, value):
self.__dict__[key]=value
def __delitem__(self, key):
print('del obj[key]时,我执行')
self.__dict__.pop(key)
def __delattr__(self, item):
print('del obj.key时,我执行')
self.__dict__.pop(item) f1=Foo('sb')
f1['age']=18
f1['age1']=19
del f1.age1
del f1['age']
f1['name']='alex'
print(f1.__dict__)

最后给两道大题压压惊

一、曾经的一道面试题:

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 self.sex == other.sex:return True
#创建的对象中只要名字和性别相同,就认为是两个相同的类 p_lst = []
for i in range(84):
p_lst.append(Person('egon',i,'male'))#将84个egon传入列表中 print(p_lst)
print(set(p_lst))#set是集合,具有去重功能,其实质就是在内部实现了__hash__和__eq__方法

二、纸牌游戏题:

from collections import namedtuple
Cards=namedtuple('Cards',['ranks','suit'])
class FranchDeck:
ranks = [str(n) for n in range(2,11)] + list('JQKA')
suits = ['红心','方板','梅花','黑桃'] def __init__(self):
self._cards = [Cards(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])#Cards(ranks='2', suit='红心')Cards(ranks='2', suit='红心')
from random import choice#随机取值,choice依赖于内置的__getitem__
print(choice(deck))#Cards(ranks='J', suit='黑桃')
print(choice(deck))#Cards(ranks='2', suit='红心') from random import shuffle#洗牌,shuffle依赖于__getitem__和__setitem__
shuffle(deck)
print(deck[:5])#[Cards(ranks='Q', suit='方板'), Cards(ranks='2', suit='黑桃'), Cards(ranks='5', suit='梅花'), Cards(ranks='4', suit='方板'), Cards(ranks='2', suit='梅花')]

what' the python之面向对象(进阶)的更多相关文章

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

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

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

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

  3. Python 3 面向对象进阶

    Python 3 面向对象进阶 一.    isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的 ...

  4. day021|python之面向对象进阶1

    面向对象进阶 目录 面向对象进阶 1 继承 1.1 继承入门 1.1.1 继承基础 1.1.2 类的基本使用 1.2 多继承 1.2.1 多继承的基本使用 1.2.2 多继承以后的重复性 1.3 类的 ...

  5. python基础-面向对象进阶

    一.什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被 ...

  6. python学习------面向对象进阶

    一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object) ...

  7. python之面向对象进阶2

    封装.property装饰器 封装分为3种情况:封装对象的属性.封装类的属性.封装方法. 封装对象的属性:(在属性名前加双下划线__) class Person: def __init__(self, ...

  8. python开发面向对象进阶:反射&内置函数

    isinstance和issubclass isinstance(obj,cls)检查是否obj是否是类 cls 的对象或者子类的对象 class Foo(object): pass class ba ...

  9. Python之面向对象进阶------反射(Day26)

    一 classmethod class Classmethod_Demo(): role = 'dog' @classmethod def func(cls): print(cls.role) Cla ...

  10. python之面向对象进阶3

    1.isinstace和issubclass 2.staticmethod和classmethod 3.反射(hasattr.getattr.setattr.delattr等四个方法) 4.内置方法 ...

随机推荐

  1. LRU 算法

    LRU算法 很多Cache都支持LRU(Least Recently Used)算法,LRU算法的设计原则是:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小.也就是说,当限定 ...

  2. adb shell命令行

    d: cd D:\software\adt-bundle-windows-x86-20131030\sdk\platform-tools ————————> sdk的路径 adb shell s ...

  3. 深度学习之windows安装tensorflow

    1. 安装python3.5 2. 下载tensorflow-1.1.0rc2-cp35-cp35m-win_amd64.whl 3. pip install tensorflow-1.1.0rc2- ...

  4. 关于linux下mysql 5.7.x数据库的yum的安装方法

    环境介绍>>>>>>>>>>>>>>>>>> 操作系统:Centos 7.1 mysql数据 ...

  5. 9.25中间件和Django的学过的知识总结

    2018-9-25 12:10:54 参考连接:http://www.cnblogs.com/liwenzhou/p/8761803.html 浏览器访问Django的过程 面试时容易问到   Dja ...

  6. Jenkins解决无法获取插件的办法(升级站点目录)

    Jenkins解决无法获取插件的办法 可能是由于Jenkins的更新网站被QIANG,因此,请替换插件的服务器地址: http://mirror.xmission.com/jenkins/update ...

  7. http://202.194.116.8/webapps/portal/frameset.jsp?tab_id=_2_1&url=%2fwebapps%2fblackboard%2fexecute%2

    http://202.194.116.8/webapps/portal/frameset.jsp?tab_id=_2_1&url=%2fwebapps%2fblackboard%2fexecu ...

  8. 入手Docker容器注意事项:命令结束容器退出

    在没有 docker 容器的时候,在终端(terminal)中运行 shell 命令,我们知道当终端退出时(比如关闭终端窗口或退出 ssh 会话),终端中执行的命令也会结束.所以,当我们在终端中执行持 ...

  9. python字典查询功能

    def fetch(data): print(' 查询功能') print('用户数据是',data) def add(): pass def change(): pass def delete(): ...

  10. [No0000F2]ip安全监视器

    IPSec快速式策略 @echo off :again set num= set fastpolicyname= set issoft= set livetime= set fps= setlocal ...