py---------面向对象进阶
一、isinstance 和 issubclass
isinstance(obj,cls)检查obj是否是类cls的对象,是则返回True
- class Foo(object):
- pass
- obj = Foo()
- print(isinstance(obj,Foo))
issubclass(sub,super)检查sub类是否是supper 类的派生类
- class Foo(object):
- pass
- class Bar(Foo):
- pass
- print(issubclass(Bar,Foo))
二、反射
1、什么是反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。
2、python面向对象中的反射:
通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
四个可以实现自省的函数
下列方法适用于类和对象(一切皆对象,类本身也是一个对象)
- def hasattr(*args, **kwargs): # real signature unknown
- """
- Return whether the object has an attribute with the given name.
- This is done by calling getattr(obj, name) and catching AttributeError.
- """
- pass
hasattr
- def getattr(object, name, default=None): # known special case of getattr
- """
- getattr(object, name[, default]) -> value
- Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
- When a default argument is given, it is returned when the attribute doesn't
- exist; without it, an exception is raised in that case.
- """
- pass
getattr
- def setattr(x, y, v): # real signature unknown; restored from __doc__
- """
- Sets the named attribute on the given object to the specified value.
- setattr(x, 'y', v) is equivalent to ``x.y = v''
- """
- pass
setattr
- def delattr(x, y): # real signature unknown; restored from __doc__
- """
- Deletes the named attribute from the given object.
- delattr(x, 'y') is equivalent to ``del x.y''
- """
- pass
delattr
- class Foo:
- f = '类的静态变量'
- def __init__(self,name,age):
- self.name=name
- self.age=age
- def say_hi(self):
- print('hi,%s'%self.name)
- obj=Foo('egon',73)
- #检测是否含有某属性
- print(hasattr(obj,'name'))
- print(hasattr(obj,'say_hi'))
- #获取属性
- n=getattr(obj,'name')
- print(n)
- func=getattr(obj,'say_hi')
- func()
- print(getattr(obj,'aaaaaaaa','不存在啊')) #报错
- #设置属性
- setattr(obj,'sb',True)
- setattr(obj,'show_name',lambda self:self.name+'sb')
- print(obj.__dict__)
- print(obj.show_name(obj))
- #删除属性
- delattr(obj,'age')
- delattr(obj,'show_name')
- delattr(obj,'show_name111')#不存在,则报错
- print(obj.__dict__)
四个方法的使用演示
- class Foo(object):
- staticField = "old boy"
- def __init__(self):
- self.name = 'wupeiqi'
- 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')()
类名 反射 静态属性
对象名 反射 对象属性和方
模块 反射 模块中的名字
反射 自己所在文件中的名字
x.y 这样的形式都可以用反射
- 'aaa'.startswith('a')
- print('aaa'.startswith)
- ret = getattr('aaa','startswith') #把startswith转换为字符串来处理,就是可以通过字符串来拿打一个值
- print(ret)
- class Person:
- role = 'Person'
- def __init__(self,name):
- self.name =name
- def eat(self):print('eating')
- def drink(self):print('drinking')
- def play(self):print('playing')
- def sleep(self):print('sleeping')
- alex = Person('alex')
- print(getattr(alex,'name')) #反射 对象属性和方法
- print(getattr(Person,'role')) #反射 静态属性
- while True:
- inp = input("请输入:")
- if hasattr(alex,inp): #判断alex,inp是否有内容
- getattr(alex,inp)()
- 首先 getattr获取一个名字,如果在这个对象的命名空间中没有这个名字会报错
getattr的反射好伴侣hasatter 一般同时出现
如果使用getattr获取一个方法,那么只能拿到这个方法的内存地址 加上括号执行
模块反射
- #模块 mymodule.py内容
- # 模块就是一个py文件
- # 所谓的模块导入 就是执行了这个文件而已
- money = 100
- def func1():
- print('func1')
- def func2():
- print('func2')
- class Manager:
- def eat(self):
- print('eating')
mymodule.py
- import mymodule
- import time
- #原来方法
- print(mymodule.money)
- print(mymodule.func1())
- Manager = mymodule.Manager
- a = Manager()
- a.eat()
- #反射
- print(getattr(mymodule,'money'))
- print(getattr(mymodule,'func1')())
- Manager = getattr(mymodule,'Manager')
- b = Manager()
- b.eat()
模块反射
反射自己所在文件中的名字
- import sys
- value = ''
- print(sys.modules['__main__']) #拿到自己模块
- print(getattr(sys.modules['__main__'],'value')) #拿到123 反射自己模块名字
__str__和__repr__
改变对象的字符串显示__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))
- print('from str: ',str(s1))
- print(s1)
- '''
- str函数或者print函数--->obj.__str__()
- repr或者交互式解释器--->obj.__repr__()
- 如果__str__没有被定义,那么就会使用__repr__来代替输出
- 注意:这俩方法的返回值必须是字符串,否则抛出异常
- '''
- print(format(s1,'nat'))
- print(format(s1,'tna'))
- print(format(s1,'tan'))
- print(format(s1,'asfdasdffd'))
- class B:
- def __str__(self):
- return 'str : class B'
- def __repr__(self):
- return 'repr : class B'
- b=B()
- print('%s'%b)
- print('%r'%b)
- %s和%r
%s和%r
__del__
析构方法,当对象在内存中被释放时,自动触发执行。
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
- class Foo:
- def __del__(self):
- print('执行我啦')
- f1=Foo()
- del f1
- print('------->')
- #输出结果
- 执行我啦
- ------->
简单示范
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__)
__new__
- class A:
- def __init__(self):
- self.x = 1
- print('in init function')
- def __new__(cls, *args, **kwargs):
- print('in new function')
- return object.__new__(A, *args, **kwargs)
- a = A()
- print(a.x)
- 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()
- two.a = 3
- print(one.a)
- #
- # one和two完全相同,可以用id(), ==, is检测
- print(id(one))
- #
- print(id(two))
- #
- print(one == two)
- # True
- print(one is two)
单例模式
- #先执行new方法,object.__new__()
- #在执行init
- # __new__ 构造方法 创建一个对象
- # __init__ 初始化方法
- class Foo:
- def __new__(cls, *args, **kwargs):
- print('执行我啦')
- obj = object.__new__(cls)
- print(obj)
- return obj
- def __init__(self):
- print('',self)
- Foo()
- # 先执行new方法,object.new()
- # 再执行init
- # Foo() --> python解释器接收到你的python代码
- # python解释器替你去做了很多操作
- # 包括 主动帮助你 调用 new方法 去创造一个对象 —— 开辟内存空间 —— python语言封装了开辟内存的工作
- # object的new方法里 —— 帮你创造了对象
- # 调用init用到的self参数 就是new帮你创造的对象
- 什么叫单例模式
- # 单例模式 : 某一类 只有一个实例
- class Person:
- __isinstance = None
- def __new__(cls, *args, **kwargs):
- if not cls.__isinstance :
- obj = object.__new__(cls)
- cls.__isinstance = obj
- return cls.__isinstance
- def __init__(self,name):
- self.name = name
- alex = Person('alex')
- alex.age = 18
- egon = Person('egon')
- print(egon.age)
- print(id(alex))
- print(id(egon))
- print(alex.name) #egon指向同一个内存地址,后覆盖前面的
- print(egon.name) #egon
- # __new__生孩子
- # 类 : 生一个小孩__new__ 给这个小孩穿衣服 __init__
- # 单例模式下的类 : 只有一个小孩,内存空间还是原来的内存空间
单例模式
__call__
对象后面加括号,触发执行。
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
- class Foo:
- def __init__(self):
- pass
- def __call__(self, *args, **kwargs):
- print('__call__')
- obj = Foo() # 执行 __init__
- obj() # 执行 __call__
__len__
- class A:
- def __init__(self):
- self.a = 1
- self.b = 2
- def __len__(self):
- return len(self.__dict__)
- a = A()
- print(len(a))
__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))
__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)
- 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
纸牌游戏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 self.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))
- 一道面试题
面试题
- class Person:
- def __init__(self,name):
- self.name = name
- def __str__(self):
- return 'a object of Person named %s'%self.name
- # def __hash__(self): #
- # return 1231212
- # def __len__(self):
- # return 10
- a = Person('alex')
- b = Person('egon')
- # print(len(a))
- # print(hash(a))
- print(a)
- # print(b)
- # 类中的内置方法 很多都和 内置函数相关
- # l = list([1,2,3]) # 实例化
- # print(l) # 之所以可以打印出结果,是因为def __str__(self): 定义了,需要定义str
详解python实现线程安全的单例模式
单例模式是一种常见的设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。
比如,服务器的配置信息写在一个文件中online.conf中,客户端通过一个 Config 的类来读取配置文件的内容。如果在程序运行期间,有很多地方都需要使用配置文件的内容,那么每个调用配置文件的地方都会创建 Config的实例,这就导致系统中存在多个Config 的实例对象,在配置文件内容很多的情况下,我们就浪费了大量的内存做了同样的事。事实上,对于Config类我们在程序运行期间时只需要一个实例对象即可,这时单例模式就是最好的选择。
- def Singleton(cls):
- instances = {}
- def get_instance(*args, **kw):
- if cls not in instances:
- instances[cls] = cls(*args, **kw)
- return instances[cls]
- return get_instance
代码也很简单,将类传入单例修饰器中,如果该类还未生成实例(instances中不存在该类),那么就生成一个新的实例返回,并记录在instances中。如果已经instances中已经存在该类,那么直接返回实例instances[cls]。
那么这段代码是完美的吗?答案是否定的,这段代码不是线程安全的。要实现线程安全需要配合锁的使用,只有占有锁的线程才能继续访问单例实例,看来我们需要再写一个修饰器来实现线程安全了,以下是完整的代码实现和简单的多线程测试用例。
- #!/usr/bin/python
- # -*- coding: utf-8 -*-
- import threading
- def synchronized(func):
- func.__lock__ = threading.Lock()
- def synced_func(*args, **kws):
- with func.__lock__:
- return func(*args, **kws)
- return synced_func
- def Singleton(cls):
- instances = {}
- @synchronized
- def get_instance(*args, **kw):
- if cls not in instances:
- instances[cls] = cls(*args, **kw)
- return instances[cls]
- return get_instance
- def worker():
- single_test = test()
- print "id----> %s" % id(single_test)
- @Singleton
- class test():
- a = 1
- if __name__ == "__main__":
- task_list = []
- for one in range(30):
- t = threading.Thread(target=worker)
- task_list.append(t)
- for one in task_list:
- one.start()
- for one in task_list:
- one.join()
py---------面向对象进阶的更多相关文章
- Python全栈开发【面向对象进阶】
Python全栈开发[面向对象进阶] 本节内容: isinstance(obj,cls)和issubclass(sub,super) 反射 __setattr__,__delattr__,__geta ...
- day26、面向对象进阶:多态、封装、反射
一.多态 什么是多态: 类的继承有两层意义:1.改变 2.扩展 多态就是类的这两层意义的一个具体的实现机. 即:调用不同类实例化的对象,下的相同的方法,实现的过程不一样 python中的标准类型就是多 ...
- python基础——面向对象进阶
python基础--面向对象进阶 1.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 ...
- 周末班:Python基础之面向对象进阶
面向对象进阶 类型判断 issubclass 首先,我们先看issubclass() 这个内置函数可以帮我们判断x类是否是y类型的子类. class Base: pass class Foo(Base ...
- Python面向对象进阶和socket网络编程-day08
写在前面 上课第八天,打卡: 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __i ...
- 铁乐学python_day23_面向对象进阶1_反射
铁乐学python_day23_面向对象进阶1_反射 以下内容大部分摘自博客http://www.cnblogs.com/Eva-J/ isinstance()和issubclass() 两者的返回值 ...
- python_面向对象进阶(7)
第1章 面向对象特性—继承(补充) 1.1 接口类.抽象类介绍 1.2 接口类 1.3 接口类应用过程 1.3.1 第一版:完成多种支付方式接口 1.3.2 第二版: 归一化设计,统一支付方式 1.3 ...
- ~~面向对象进阶——__name__=="__main__"~~
进击のpython 面向对象进阶--__name__=="__main__" 前面我们在讲模块的时候,其实还有一个知识点没有很好的讲 那就是main和name 可能你们在看一些代码 ...
- Python面向对象进阶和socket网络编程
写在前面 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __init__(self ...
- Py-多态,封装,反射,描述符,包装标准类型,面向对象进阶
多态: 对象可以通过他们共同的属性和动作来访问,而不需要考虑他们的类多态是继承的应用 class H2o: def __init__(self,temp): self.temp=temp def ht ...
随机推荐
- ROS Learning-014 learning_tf(编程) 坐标系变换(tf)广播员 (Python版)
ROS Indigo learning_tf-01 坐标系变换(tf)广播员 (Python版) 我使用的虚拟机软件:VMware Workstation 11 使用的Ubuntu系统:Ubuntu ...
- 杭电acm 1038题
本题比较简单,但是需要掌握几个小技巧,先上代码 /************************************* 杭电ACM 1038题,已AC ********************* ...
- Win10 VS2013 PCL1.8.1和依赖项VTK8.0.1, QHuall(2.15.2), FLANN1.9.1,Boost1.59.0,Zbil1.2.11和libPNG1.6.34编译安装
编译和安装过程最好使用管理员权限去操作,避免不必要的错误. 一般而言为了区分Debug和Release库,添加输入变量 Name: CMAKE_DEBUG_POSTFIX Type: STRING V ...
- vue 之 指令系统介绍
浏览目录 条件渲染 class 与style绑定 事件处理 指令系统介绍 所谓指令系统,大家可以联想咱们的cmd命令行工具,只要我输入一条正确的指令,系统就开始干活了. 在vue中,指令系统,设置一些 ...
- Charles常见问题汇总
Charles是一款很好用的抓包修改工具,但是如果你不是很熟悉这个工具的话,肯定会遇到各种感觉很莫名其妙的状况,这里就来帮你一一解答下面再说说charles的一些其他常用的功能. 选择请求后,右键可以 ...
- 解决批处理命令执行完毕后自动关闭cmd窗口方法
问题描述: 日常开发工作中,为了节省多余操作导致浪费时间,我们经常会自己建一些批处理脚本文件(xx.bat),文件中包含我们需要执行的命令,有时候我们希望执行完毕后看一下执行的结果,但是窗口执行完毕后 ...
- 安装windows系统备忘
1.已写入系统镜像的U盘 2.激活工具(同时激活系统及office) 3.如果没有网口或网线,需要准备万能网卡驱动 4.office 5.360 6.输入法 7.微信 8.谷歌浏览器
- 依赖注入(DI)与控制反转(IOC)
DI(依赖注入,Dependency Injection),和所谓的IoC(控制反转,Inversion of Control )是一个意思. DI是一种通过接口实现松耦合的设计模式.初学者可能会好奇 ...
- 前端的异步解决方案之Promise和Await-Async
异步编程模式在前端开发过程中,显得越来越重要.从最开始的XHR到封装后的Ajax都在试图解决异步编程过程中的问题.随着ES6新标准的出来,处理异步数据流的解决方案又有了新的变化.Promise就是这其 ...
- [51nod1222] 最小公倍数计数(莫比乌斯反演)
题面 传送门 题解 我此生可能注定要和反演过不去了--死都看不出来为啥它会突然繁衍反演起来啊-- 设\(f(n)=\sum_{i=1}^n\sum_{j=1}^n[{ij\over\gcd(i,j)} ...