一、isinstance(obj, cls) & issubclass(sub, super)

isinstance(obj, cls)

检查是否obj是否是类 cls 的对象

1
2
3
4
5
6
class Foo(object):
    pass
  
obj = Foo()
  
isinstance(obj, Foo)

issubclass(sub, super)

检查sub类是否是 super 类的派生类

1
2
3
4
5
6
7
class Foo(object):
    pass
  
class Bar(Foo):
    pass
  
issubclass(Bar, Foo)

二、反射

python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。

# commons.py 文件

name = "nick"

def f1():
return "This is f1." def f2():
return "This is f2." def nb():
return "This is niubily." # index.py 文件
import commons #根据字符串的形式去某个模块中寻找东西
target_func = getattr(commons,"f1") # 找函数
result = target_func()
print(result) target_func = getattr(commons,"name") # 找全局变量
print(target_func) target_func = getattr(commons,"age",None) # 找不到返回None
print(target_func) #根据字符串的形式去某个模块中判断东西是否存在
tarhas_func = hasattr(commons,"f5") # 找函数
print("before:",tarhas_func) # tarhas_func = hasattr(commons,"name") # 找全局变量
# print(tarhas_func) #根据字符串的形式去某个模块中设置东西
setattr(commons,"f5","lambda x: return \"This is new func.\"") # 设置一个函数
setattr(commons,"age",) # 设置全局变量 tarhas_func = hasattr(commons,"f5") # 检查函数是否存在
print("after:",tarhas_func) #根据字符串的形式去某个模块中删除东西
delattr(commons,"f5") # 删除一个函数 tarhas_func = hasattr(commons,"f5") # 检查函数是否存在
print("end:",tarhas_func)
# 通过字符串的形式,导入模块。起个别名 ccas。

comm = input("Please:")
ccas = __import__(comm)
ccas.f1() # 需要做拼接导入时后加 fromlist=True(否则只导入lib)
ccas = __import__("lib."+comm, fromlist=True)

补充__import__

##### 路由系统 #####

# 输入 模块名/函数名  (例如:commons/nb)
url = input("Please input you want url:") target_module, target_func = url.split("/") #m = __import__("lib."+target_module,fromlist=True)
m = __import__(target_module) if hasattr(m,target_func):
target_func = getattr(m,target_func)
result = target_func()
print(result)
else:
print("Sorry,it's 404 not found.") 路由系统

路由系统

三、类装饰器

def deco(func):
print('===================')
return func #fuc=test @deco #test=deco(test)
def test():
print('test函数运行')
test()

框架

def deco(obj):
print('============',obj)
obj.x= #增加属性
obj.y=
obj.z=
return obj @deco #Foo=deco(Foo) #@deco语法糖的基本原理
class Foo:
pass print(Foo.__dict__) #加到类的属性字典中 输出
============ <class '__main__.Foo'>
{'__module__': '__main__', 'z': , 'x': , '__dict__': <attribute '__dict__' of 'Foo' objects>, '__doc__': None, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, 'y': }

对类增加类属性

def Typed(**kwargs):
def deco(obj):
for key,val in kwargs.items():
setattr(obj,key,val)
return obj
return deco @Typed(x=,y=,z=) #typed(x=,y=,z=)--->deco
class Foo:
pass
print(Foo.__dict__) @Typed(name='egon')
class Bar:
pass
print(Bar.name) 控制台输出
{'y': , '__dict__': <attribute '__dict__' of 'Foo' objects>, 'z': , '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__module__': '__main__', 'x': , '__doc__': None} egon 增强版

多一例

四、元类

ython中一切皆是对象,类本身也是一个对象,当使用关键字class的时候,python解释器在加载class的时候就会创建一个对象(这里的对象指的是类而非类的实例)

寻找类的父亲

#type函数可以查看类型,也可以用来查看对象的类,二者是一样的
print(type(f1)) # 输出:<class '__main__.Foo'> 表示,obj 对象由Foo类创建
print(type(Foo)) # 输出:<type 'type'>
  • 元类是类的类,是类的模板
  • 元类是用来控制如何创建类的,正如类是创建对象的模板一样
  • 元类的实例为类,正如类的实例为对象(f1对象是Foo类的一个实例Foo类是 type 类的一个实例)
  • type是python的一个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象

一个类没有声明自己的元类,默认它的元类就是type,除了使用元类type,用户也可以通过继承type来自定义元类(顺便我们也可以瞅一瞅元类如何控制类的创建,工作流程是什么)

class Mytype(type):
def __init__(self,a,b,c):
print(self)
print(a)
print(b)
print(c)
def __call__(self, *args, **kwargs):
print("call") class Slamdunk(metaclass=Mytype): # Mytype("Slamdunk",(object,),{}) 实际上就是这么做,但是传了4个参数
# 声明Foo类由Mytype创建,声明自己的元类
def __init__(self,name):
self.name = name s1 = Slamdunk("樱木花道")
# 根据python一切皆对象,Slamdunk() 本质上就是在触发创建 Slamdunk类的 元类的__call__ 控制台输出
<class '__main__.Slamdunk'> # 元类创建的实例(对象)
Slamdunk # 实例名
() # 继承的类,在python3中都默认继承object,即都为新式类
{'__qualname__': 'Slamdunk', '__init__': <function Slamdunk.__init__ at 0x000002106AFBF840>, '__module__': '__main__'} # 实例类的属性字典
call # 实例+() 触发了元类的__call__方法 模拟初步认识
class Mytype(type):
def __init__(self,a,b,c):
print(self)
def __call__(self, *args, **kwargs): # 传的值是怎么传进去的,就去怎么接收
print("call")
obj = object.__new__(self) # 生成一个实例
self.__init__(obj,*args,**kwargs) # 这里的self是Mytype产生的实例,这一步触发 Slamdunk 的构造方法
return obj # __call__方法下的返回值是 self 产生的实例 赋值给s1
class Slamdunk(metaclass=Mytype):
# Slamdunk = Mytype("Slamdunk",(object,),{}) 实际上就是这么做,但是传了4个参数
# 声明Foo类由Mytype创建,声明自己的元类
# 触发元类的__init__(元类的构造方法)
def __init__(self,name):
self.name = name
s1 = Slamdunk("樱木花道")
# 根据python一切皆对象,Slamdunk() 本质上就是在触发创建 Slamdunk类的 元类的__call__
print(s1.__dict__) # 可以访问到实例对象的属性字典
class Mytype(type):
def __init__(self,a,b,c):
print(self)
def __call__(self, *args, **kwargs):
obj = object.__new__(self)
self.__init__(obj,*args,**kwargs)
return obj
class Slamdunk(metaclass=Mytype):
def __init__(self,name):
self.name = name
s1 = Slamdunk("樱木花道")
print(s1.__dict__) 控制台输出
<class '__main__.Slamdunk'>
{'name': '樱木花道'} # 可以加断点体验 实现创建类的流程 精简版

实现创建类的流程 精简版

五、单例模式

   单例模式存在的目的是保证当前内存中仅存在单个实例

  (程序如果并发量大的话,内存里就会存在非常多功能上一模一样的对象。存在这些对象肯定会消耗内存,对于这些功能相同的对象可以在内存中仅创建一个,需要时都去调用)

初级:

# 单例模式

class Foo:

    __n = None

    def __init__(self):
self.name = "nick"
self.age =
self.job = "pythoner" @staticmethod
def dl():
if Foo.__n:
return Foo.__n
else:
Foo.__n = Foo()
return Foo.__n # 创建对象时不能再直接使用:obj = Foo(),而应该调用特殊的方法:obj = Foo.dl() 。 f1 = Foo.dl()
print(f1)
f2 =Foo.dl()
print(f2)
f3 =Foo.dl()
print(f3) # 运行结果
<__main__.Foo object at 0x0000000001142390>
<__main__.Foo object at 0x0000000001142390>
<__main__.Foo object at 0x0000000001142390>

装饰器方式单例模式

# 装饰器方式单例模式

def singleton(argv):
dic = {} def s(*args, **kwargs): if argv not in dic:
dic[argv] = argv(*args, **kwargs)
return dic[argv]
else:
return dic[argv] return s # 类上加单例装饰器
@singleton
class Foo:
pass @singleton
class Foo2:
pass

升级:

from abc import abstractmethod, ABCMeta

class Singleton(object):
def __new__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance class MyClass(Singleton):
def __init__(self, name=None):
if name:
self.name = name a = MyClass("a") print(a)
print(a.name) b = MyClass('b')
#
print(b)
print(b.name)
#
print(a)
print(a.name)

Python修炼10------面向对象的更多相关文章

  1. Python学习--10 面向对象编程

    面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 本节对于面向对象的概念不做 ...

  2. Python开发——10.面向对象编程进阶

    一.isinstance(obj,cls)和issubclass(sub,super) 1.isinstance(obj,cls) 判断obj是不是由cls产生的类 2.issubclass(sub, ...

  3. python学习笔记(10):面向对象

    一.类和实例 1.类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 2.对象:通过类定义的数据结构实例.对象包括两个数据成员( ...

  4. python高级之面向对象高级

    python高级之面向对象高级 本节内容 成员修饰符 特殊成员 类与对象 异常处理 反射/自省 单例模式 1.成员修饰符 python的类中只有私有成员和公有成员两种,不像c++中的类有公有成员(pu ...

  5. 8.python笔记之面向对象基础

    title: 8.Python笔记之面向对象基础 date: 2016-02-21 15:10:35 tags: Python categories: Python --- 面向对象思维导图 (来自1 ...

  6. 第四篇:python 高级之面向对象初级

    python 高级之面向对象初级   python 高级之面向对象初级 本节内容 类的创建 类的构造方法 面向对象之封装 面向对象之继承 面向对象之多态 面向对象之成员 property 1.类的创建 ...

  7. 第五篇:python高级之面向对象高级

    python高级之面向对象高级   python高级之面向对象高级 本节内容 成员修饰符 特殊成员 类与对象 异常处理 反射/自省 单例模式 1.成员修饰符 python的类中只有私有成员和公有成员两 ...

  8. Python 基础 四 面向对象杂谈

    Python 基础  四  面向对象杂谈 一.isinstance(obj,cls) 与issubcalss(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls ...

  9. python修炼第一天

    Python修炼第一天 新的开始:不会Python的运维,人生是不完整的. 为了我的人生能够完整,所以我来了!今后跟着太白金星师傅学习功夫,记录一下心得,以便日后苦练. 一 Python的历史: Py ...

  10. 自学Python之路-Python基础+模块+面向对象+函数

    自学Python之路-Python基础+模块+面向对象+函数 自学Python之路[第一回]:初识Python    1.1 自学Python1.1-简介    1.2 自学Python1.2-环境的 ...

随机推荐

  1. 去除scons构建动态库的前缀lib

    如何使用scons构建工程,请参考快速构建C++项目工具Scons,结合Editplus搭建开发环境. 编译SharedLibrary项目的时候,生产的so文件时自动加上lib, 例如: env = ...

  2. 关闭Windows 2008下面应用程序出错后的提示

    写了一个服务器端程序,没有能处理所有的错误,总有一些错误会抛出到系统中去.于是写了一个进程守护者,一旦发现服务器端退出,可以在第一时间重新启动服务器,也算是一种折中的方案吧.理论上讲应该是可行的,但是 ...

  3. ASP.NET Zero--5.配置权限

    修改角色的时候,会有一份权限列表,可以给这个角色分配哪些权限,那如何添加一个新权限呢?   这里以添加一个“测试”的权限为例 1.打开AppPermissions.cs [..\MyCompanyNa ...

  4. Python自动化开发-变量、数据类型和运算

    一.变量 变量定义:Variables are used to store infomation to referrenced and manipulated in a computer progra ...

  5. 浅谈href=#与href=javascript:void(0)的区别

    #"包含了一个位置信息 默认的锚点是#top 也就是网页的上端 而javascript:void(0)  仅仅表示一个死链接 这就是为什么有的时候页面很长浏览链接明明是#可是跳动到了页首 而 ...

  6. HTML5之Audio音频标签学习

    HTML5中的新元素标签 src:音频文件路径. autobuffer:设置是否在页面加载时自动缓冲音频. autoplay:设置音频是否自动播放. loop:设置音频是否要循环播放. control ...

  7. OO的五大原则:SRP、OCP、LSP、DIP、ISP

    OO的五大原则是指SRP.OCP.LSP.DIP.ISP. SRP -- (Single Responsibility Principle 单一职责原则) OCP--开闭原则(Closed for M ...

  8. python命令调用函数os.popen

    参考自xerosploit 描述:利用os.popen()函数调用系统命令nmap进行扫描,并用grep命令对扫描结果关键内容进行提取 代码 #!/usr/bin/env pthon #--*--co ...

  9. 关于一条定制长按Power键弹出Dialog的需求

    如题,需要定制长按Power键弹出的Dialog,UI上的大致效果是:全屏,中间下拉按钮“Swipe Down To Power Off”下拉关机,底部左右两侧“Reboot”,“Cancel”按钮, ...

  10. SUSE Linux 下redis 的坑

    前面redis服务器安装-SuSE Linux Enterprise Server 11 SP3一章中安装好提示开放防火墙后的一些坑 前面漏了说明redis作为一个高速数据库,在互联网上,对应的安全机 ...