一、检查isinstance(obj,cls)和issubclass(sub,super)

class Foo(object):passobj = Foo()isinstance(obj, Foo)
##判断obj是否是Foo对象

class Foo(object):passclass Bar(Foo):passissubclass(Bar, Foo)
##判断Bar是否是Foo的派生类

二、反射python面向对象中的反射:通过字符串的形式操作对象相关的属性

#hasattr(obj,str)
#getattr(obj,str)
#setattr(obj,key,value)
#delattr(obj,str)
class BlackMedium:feature='Ugly'def __init__(self,name,addr):self.name=nameself.addr=addrdef sell_house(self):print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' %self.name)def rent_house(self):print('%s 黑中介租房子啦,傻逼才租呢' %self.name)b1=BlackMedium('万成置地','回龙观天露园')#检测是否含有某属性
print(hasattr(b1,'name'))
print(hasattr(b1,'sell_house'))#获取属性
n=getattr(b1,'name')
print(n)
func=getattr(b1,'rent_house')
func()# getattr(b1,'aaaaaaaa') #报错
print(getattr(b1,'aaaaaaaa','不存在啊'))#设置属性
setattr(b1,'sb',True)
setattr(b1,'show_name',lambda self:self.name+'sb')
print(b1.__dict__)
print(b1.show_name(b1))#删除属性
delattr(b1,'addr')
delattr(b1,'show_name')
delattr(b1,'show_name111')#不存在,则报错print(b1.__dict__)四个方法的使用演示

class Foo(object):staticField = "old boy"def __init__(self):self.name = 'wupeiqi'def func(self):return 'func'@staticmethoddef bar():return 'bar'print getattr(Foo, 'staticField')
print getattr(Foo, 'func')
print getattr(Foo, 'bar')类也是对象

egon式教学,类也是对象

#!/usr/bin/env python
# -*- coding:utf-8 -*-import sysdef s1():print 's1'def s2():print 's2'this_module = sys.modules[__name__]hasattr(this_module, 's1')
getattr(this_module, 's2')反射当前模块成员

反射当前模块

导入其他模块

module_test

#!/usr/bin/env python
# -*- coding:utf-8 -*-def test():print('from the test')

module_test.py

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

index.py

反射的好处

可插拔机制:A出去游玩而代码的某些功能没有写完,我想加班把代码赶完,而且需要使用A没有写完的功能

B没有完成的代码

class FtpClient:'ftp客户端,但是还么有实现具体的功能'def __init__(self,addr):print('正在连接服务器[%s]' %addr)self.addr=addr

我就可以使用反射机制来完成自己的逻辑们只需要提前定义好接口就可以

#from module import FtpClient
f1=FtpClient('192.168.1.1')
if hasattr(f1,'get'):func_get=getattr(f1,'get')func_get()
else:print('---->不存在此方法')print('处理其他的逻辑')

server_ftp

好处二,实现动态导入模块

简单粗暴直接上代码

###

三、__setattr__、__getattr__、__delattr__

粗暴玩法

class Foo:x=1def __init__(self,y):self.y=ydef __getattr__(self, item):print('----> from getattr:你找的属性不存在')def __setattr__(self, key, value):print('----> from setattr')# self.key=value #这就无限递归了,你好好想想# self.__dict__[key]=value #应该使用它def __delattr__(self, item):print('----> from delattr')# del self.item #无限递归了self.__dict__.pop(item)#__setattr__添加/修改属性会触发它的执行
f1=Foo(10)
print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
f1.z=3
print(f1.__dict__)#__delattr__删除属性的时候会触发
f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作
del f1.a
print(f1.__dict__)#__getattr__只有在使用点调用属性且属性不存在的时候才会触发
f1.xxxxxx三者的用法演示

这三种方法可以添加、修改、删除__dict__

修改和赋值触发__setattr__、删除变量触发__delattr__、当不在__dict__中,触发__getattr__(使用obj.方式调用属性)

四、包装

包装:python提供了标准数据类型,以及丰富的内置方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增/改写方法,这就用到了我们刚学的继承/派生知识(其他的标准类型均可以通过下面的方式进行二次加工)

class List(list): #继承list所有的属性,也可以派生出自己新的,比如append和middef append(self, p_object):' 派生自己的append:加上类型检查'if not isinstance(p_object,int):raise TypeError('must be int')super().append(p_object)@propertydef mid(self):'新增自己的属性'index=len(self)//2return self[index]l=List([1,2,3,4])
print(l)
l.append(5)
print(l)
# l.append('1111111') #报错,必须为int类型print(l.mid)#其余的方法都继承list的
l.insert(0,-123)
print(l)
l.clear()
print(l)二次加工标准类型(基于继承实现)

定制自己的list

授权:授权是包装的一个特性, 包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原有产品的功能。其它的则保持原样。授权的过程,即是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。

实现授权的关键点就是覆盖__getattr__方法

import time
class FileHandle:def __init__(self,filename,mode='r',encoding='utf-8'):self.file=open(filename,mode,encoding=encoding)def write(self,line):t=time.strftime('%Y-%m-%d %T')self.file.write('%s %s' %(t,line))def __getattr__(self, item):return getattr(self.file,item)f1=FileHandle('b.txt','w+')
f1.write('你好啊')
f1.seek(0)
print(f1.read())
f1.close()

写自己的open函数

#_*_coding:utf-8_*_
#我们来加上b模式支持
import time
class FileHandle:def __init__(self,filename,mode='r',encoding='utf-8'):if 'b' in mode:self.file=open(filename,mode)else:self.file=open(filename,mode,encoding=encoding)self.filename=filenameself.mode=modeself.encoding=encodingdef write(self,line):if 'b' in self.mode:if not isinstance(line,bytes):raise TypeError('must be bytes')self.file.write(line)def __getattr__(self, item):return getattr(self.file,item)def __str__(self):if 'b' in self.mode:res="<_io.BufferedReader name='%s'>" %self.filenameelse:res="<_io.TextIOWrapper name='%s' mode='%s' encoding='%s'>" %(self.filename,self.mode,self.encoding)return res
f1=FileHandle('b.txt','wb')
# f1.write('你好啊啊啊啊啊') #自定制的write,不用在进行encode转成二进制去写了,简单,大气
f1.write('你好啊'.encode('utf-8'))
print(f1)
f1.close()

View Code

class List:def __init__(self,seq,permission=False):self.seq=seqself.permission=permissiondef clear(self):if not self.permission:raise PermissionError('not allow the operation')self.seq.clear()def __getattr__(self, item):return getattr(self.seq,item)def __str__(self):return str(self.seq)
l=List([1,2,3])
# l.clear() #此时没有权限,抛出异常
l.permission=True
print(l)
l.clear()
print(l)#基于授权,获得insert方法
l.insert(0,-123)
print(l)

加上权限的list(基于授权)

五、property

把函数的返回值定制成变量形式

class Foo:@propertydef AAA(self):print('get的时候运行我啊')@AAA.setterdef AAA(self,value):print('set的时候运行我啊')@AAA.deleterdef AAA(self):print('delete的时候运行我啊')#只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter
f1=Foo()
f1.AAA
f1.AAA='aaa'
del f1.AAA

初识用法

class Foo:def get_AAA(self):print('get的时候运行我啊')def set_AAA(self,value):print('set的时候运行我啊')def delete_AAA(self):print('delete的时候运行我啊')AAA=property(get_AAA,set_AAA,delete_AAA) #内置property三个参数与get,set,delete一一对应

f1=Foo()
f1.AAA
f1.AAA='aaa'
del f1.AAA

次识用法

class Goods:def __init__(self):# 原价self.original_price = 100# 折扣self.discount = 0.8@propertydef price(self):# 实际价格 = 原价 * 折扣new_price = self.original_price * self.discountreturn new_price@price.setterdef price(self, value):self.original_price = value@price.deleterdef price(self):del self.original_priceobj = Goods()
obj.price         # 获取商品价格
obj.price = 200   # 修改商品原价
print(obj.price)
del obj.price     # 删除商品原价

实战1

#实现类型检测功能#第一关:
class People:def __init__(self,name):self.name=name@propertydef name(self):return self.name# p1=People('alex') #property自动实现了set和get方法属于数据描述符,比实例属性优先级高,所以你这面写会触发property内置的set,抛出异常#第二关:修订版class People:def __init__(self,name):self.name=name #实例化就触发property
@propertydef name(self):# return self.name #无限递归print('get------>')return self.DouNiWan@name.setterdef name(self,value):print('set------>')self.DouNiWan=value@name.deleterdef name(self):print('delete------>')del self.DouNiWanp1=People('alex') #self.name实际是存放到self.DouNiWan里
print(p1.name)
print(p1.name)
print(p1.name)
print(p1.__dict__)p1.name='egon'
print(p1.__dict__)del p1.name
print(p1.__dict__)#第三关:加上类型检查
class People:def __init__(self,name):self.name=name #实例化就触发property
@propertydef name(self):# return self.name #无限递归print('get------>')return self.DouNiWan@name.setterdef name(self,value):print('set------>')if not isinstance(value,str):raise TypeError('必须是字符串类型')self.DouNiWan=value@name.deleterdef name(self):print('delete------>')del self.DouNiWanp1=People('alex') #self.name实际是存放到self.DouNiWan里
p1.name=1

实战2

六、 __setitem__,__getitem,__delitem__

class Foo:def __init__(self,name):self.name=namedef __getitem__(self, item):print(self.__dict__[item])def __setitem__(self, key, value):self.__dict__[key]=valuedef __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__)

[]的三剑客

七、__slots__

######################__solts__节省内存,让类没有__dict__字典,严格定义对象属性
from collections import Iterable,Iteratorclass people:__slots__ = ['name','age','high']b=people()
b.name='egon'
b.age=18
b.high=1.5

没有__dict__

1.__slots__是什么:是一个类变量,变量值可以是列表,元祖,或者可迭代对象,也可以是一个字符串(意味着所有实例只有一个数据属性)
2.引子:使用点来访问属性本质就是在访问类或者对象的__dict__属性字典(类的字典是共享的,而每个实例的是独立的)
3.为何使用__slots__:字典会占用大量内存,如果你有一个属性很少的类,但是有很多实例,为了节省内存可以使用__slots__取代实例的__dict__
当你定义__slots__后,__slots__就会为实例使用一种更加紧凑的内部表示。实例通过一个很小的固定大小的数组来构建,而不是为每个实例定义一个
字典,这跟元组或列表很类似。在__slots__中列出的属性名在内部被映射到这个数组的指定小标上。使用__slots__一个不好的地方就是我们不能再给
实例添加新的属性了,只能使用在__slots__中定义的那些属性名。
4.注意事项:__slots__的很多特性都依赖于普通的基于字典的实现。另外,定义了__slots__后的类不再 支持一些普通类特性了,比如多继承。大多数情况下,你应该
只在那些经常被使用到 的用作数据结构的类上定义__slots__比如在程序中需要创建某个类的几百万个实例对象 。
关于__slots__的一个常见误区是它可以作为一个封装工具来防止用户给实例增加新的属性。尽管使用__slots__可以达到这样的目的,但是这个并不是它的初衷。           更多的是用来作为一个内存优化工具。

egon的豪言壮语

class Foo:__slots__=['name','age']f1=Foo()
f1.name='alex'
f1.age=18
print(f1.__slots__)f2=Foo()
f2.name='egon'
f2.age=19
print(f2.__slots__)print(Foo.__dict__)
#f1与f2都没有属性字典__dict__了,统一归__slots__管,节省内存

刨根问底

深究

八、__next__和__iter__实现迭代器协议

#_*_coding:utf-8_*_
__author__ = 'Linhaifeng'
class Foo:def __init__(self,x):self.x=xdef __iter__(self):return selfdef __next__(self):n=self.xself.x+=1return self.xf=Foo(3)
for i in f:print(i)

初始迭代协议

class Foo:def __init__(self,start,stop):self.num=startself.stop=stopdef __iter__(self):return selfdef __next__(self):if self.num >= self.stop:raise StopIterationn=self.numself.num+=1return nf=Foo(1,5)
from collections import Iterable,Iterator
print(isinstance(f,Iterator))for i in Foo(1,5):print(i)

写出自己的range

class Fib:def __init__(self):self._a=0self._b=1def __iter__(self):return selfdef __next__(self):self._a,self._b=self._b,self._a + self._breturn self._af1=Fib()print(f1.__next__())
print(next(f1))
print(next(f1))for i in f1:if i > 100:breakprint('%s ' %i,end='')

斐波那契数列

九、__doc__

class Foo:'我是描述信息'passclass Bar(Foo):pass
print(Bar.__doc__) #该属性无法继承给子类

无法被继承的

十、__del__

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

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

###########################__del__当调用基数为0即对象被清除时候会被执行(析构函数)  __doc__注释,不会被继承
class Open:def __init__(self,path,mode='a+',encoding='utf-8'):self.f=open(path,mode=mode,encoding=encoding)def __getattr__(self, item):return getattr(self.f,item)def __enter__(self):  #使用with as 开始时执行(或with)print('已经开始')return selfdef __del__(self):print('清理')def __exit__(self, exc_type, exc_val, exc_tb): #使用with as 结束时执行
        self.f.close()print("已经结束,正在清理")return True# 处理异常后返回真,可以使程序不推出异常
with Open('111') as f:f.write("\n我进来了")

实现with open as f:

管理上下文协议

class Open:def __init__(self,name):self.name=namedef __enter__(self):print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')# return selfdef __exit__(self, exc_type, exc_val, exc_tb):print('with中代码块执行完毕时执行我啊')with Open('a.txt') as f:print('=====>执行代码块')# print(f,f.name)

上下文管理协议

上下文协议

__exit__()中的三个参数分别代表异常类型,异常值和追溯信息,with语句中代码块出现异常,则with后的代码都无法执行

class Open:def __init__(self,name):self.name=namedef __enter__(self):print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')def __exit__(self, exc_type, exc_val, exc_tb):print('with中代码块执行完毕时执行我啊')print(exc_type)print(exc_val)print(exc_tb)with Open('a.txt') as f:print('=====>执行代码块')raise AttributeError('***着火啦,救火啊***')
print('0'*100) #------------------------------->不会执行

View Code

如果__exit()返回值为True,那么异常会被清空,就好像啥都没发生一样,with后的语句正常执行

class Open:def __init__(self,name):self.name=namedef __enter__(self):print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')def __exit__(self, exc_type, exc_val, exc_tb):print('with中代码块执行完毕时执行我啊')print(exc_type)print(exc_val)print(exc_tb)return Truewith Open('a.txt') as f:print('=====>执行代码块')raise AttributeError('***着火啦,救火啊***')
print('0'*100) #------------------------------->会执行

View Code

用途或者说好处:

1.使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无须手动干预

2.在需要管理一些资源比如文件,网络连接和锁的编程环境中,可以在__exit__中定制自动释放资源的机制,你无须再去关系这个问题,这将大有用处

十一、__call__

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

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

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

View Code

十二、metaclass,元类

元类是类的类,是类的模板

元类是用来控制如何创建类的,正如类是创建对象的模板一样

元类的实例为类,正如类的实例为对象(f1对象是Foo类的一个实例Foo类是 type 类的一个实例)

type是python的一个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象

创建类的两种方式

一、

 class Foo:def func(self):print('from func')

View Code

二、

 def func(self):print('from func')x=1Foo=type('Foo',(object,),{'func':func,'x':1})

View Code

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

class Mytype(type):def __init__(self,class_name,bases=None,dict=None):print("Mytype init--->")print(class_name,type(class_name))print(bases)print(dict)def __call__(self, *args, **kwargs):print('Mytype call---->',self,args,kwargs)obj=self.__new__(self)self.__init__(obj,*args,**kwargs)return objclass Foo(object,metaclass=Mytype):#in python3#__metaclass__ = MyType #in python2x=1111111111def __init__(self,name):self.name=namedef __new__(cls, *args, **kwargs):return super().__new__(cls)# return object.__new__(cls) #同上
f1=Foo('name')
print(f1.__dict__)

自定制元类

class Mytype(type):def __init__(self,what,bases=None,dict=None):print('mytype init')def __call__(self, *args, **kwargs):obj=self.__new__(self)self.__init__(obj,*args,**kwargs)return objclass Foo(object,metaclass=Mytype):x=1111111111def __init__(self,name):self.name=namedef __new__(cls, *args, **kwargs):return super().__new__(cls)f1=Foo('egon')print(f1.__dict__)

自定制元类纯净版

class Mytype(type):def __init__(self,what,bases=None,dict=None):print(what,bases,dict)def __call__(self, *args, **kwargs):print('--->')obj=object.__new__(self)self.__init__(obj,*args,**kwargs)return obj
class Room(metaclass=Mytype):def __init__(self,name):self.name=namer1=Room('alex')
print(r1.__dict__)

自定制元类精简版

class Mymeta(type):def __init__(self,name,bases,dic):print('===>Mymeta.__init__')def __new__(cls, *args, **kwargs):print('===>Mymeta.__new__')return type.__new__(cls,*args,**kwargs)def __call__(self, *args, **kwargs):print('aaa')obj=self.__new__(self)self.__init__(self,*args,**kwargs)return objclass Foo(object,metaclass=Mymeta):def __init__(self,name):self.name=namedef __new__(cls, *args, **kwargs):return object.__new__(cls)'''
需要记住一点:名字加括号的本质(即,任何name()的形式),都是先找到name的爹,然后执行:爹.__call__而爹.__call__一般做两件事:
1.调用name.__new__方法并返回一个对象
2.进而调用name.__init__方法对儿子name进行初始化
''''''
class 定义Foo,并指定元类为Mymeta,这就相当于要用Mymeta创建一个新的对象Foo,于是相当于执行
Foo=Mymeta('foo',(...),{...})
因此我们可以看到,只定义class就会有如下执行效果
===>Mymeta.__new__
===>Mymeta.__init__
实际上class Foo(metaclass=Mymeta)是触发了Foo=Mymeta('Foo',(...),{...})操作,
遇到了名字加括号的形式,即Mymeta(...),于是就去找Mymeta的爹type,然后执行type.__call__(...)方法
于是触发Mymeta.__new__方法得到一个具体的对象,然后触发Mymeta.__init__方法对对象进行初始化
''''''
obj=Foo('egon')
的原理同上
''''''
总结:元类的难点在于执行顺序很绕,其实我们只需要记住两点就可以了
1.谁后面跟括号,就从谁的爹中找__call__方法执行
type->Mymeta->Foo->obj
Mymeta()触发type.__call__
Foo()触发Mymeta.__call__
obj()触发Foo.__call__
2.__call__内按先后顺序依次调用儿子的__new__和__init__方法
'''

元类总结

转载于:https://www.cnblogs.com/drchen/p/6764158.html

egon说一切皆对象--------面向对象进阶紫禁之巅相关推荐

  1. 小白IT:从0~明白带你体验python中做上帝感觉--一切皆对象,处处是多态——面向对象

    文章目录 Python 面向对象从0到基础 一.面向对象 1 面向过程VS面向对象** 2 了解一些名词: 3 类 类的声明 **类的作用:属性引用和实例化** **定义函数和类的区别** 类属性的查 ...

  2. javascript”面向对象编程”- 1万物皆对象

    javascript几乎成了如今web开发人员必学必会的一门语言,但很多人却只停在了一些表单验证等基础操作层面上,在面向对象语言大行其道的当下,我们需要去学习javascript的面向对象的知识,以便 ...

  3. python对象属性在引用时前面需要加()_python基础-面向对象进阶

    实现授权的关键点就是覆盖__getattr__方法 1.通过触发__getattr__方法,找到read方法 示例1: 1 importtime2 classFileHandle:3 def __in ...

  4. 2.1.6 面向对象:一切皆对象(Python)

    本文来自异想之旅公开发布的Python教程,原文地址:https://www.yuque.com/yxzl/python 表象展示 Python 是一门面向对象的程序设计语言,它的设计理念之一便是&q ...

  5. Python面向对象进阶和socket网络编程

    写在前面 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese:def __init__(self, ...

  6. Day 23 面向对象进阶

    目录 面向对象进阶 类的继承 什么是继承 为什么要用继承 对象的继承 对象查找属性的顺序 类的派生 类的组合 菱形继承问题 类的分类 菱形继承问题 多态与多态性 多态 多态性 面向对象进阶 类的继承 ...

  7. python class用法理解_Python小世界:彻底搞懂Python一切皆对象!

    犹记得当初学习Python的时候,对于 Python一切皆对象 很是懵逼,因为Python是面向对象的动态型语言,而在函数及高阶函数的应用中,如若对于一切皆对象不是有很透彻的了解,基础不是那么牢固的话 ...

  8. python之路——面向对象进阶

    一.isinstance和issubclass isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object):passobj = Foo()isin ...

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

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

最新文章

  1. 散列表查找(哈希表)
  2. Oracle左右全连接总结
  3. matlab分类器设计,简单分类器的MATLAB实现.doc
  4. react 实现数据双向绑定
  5. JAVA学习笔记(8)
  6. SAP CRM呼叫中心polling javascript - icf_notify_poll.js
  7. jq关于对象类型的判断
  8. opencv介绍+python调取图片
  9. java环境怎么搭,如何搭建一个完整的Java开发环境
  10. HDFS体系结构(NameNode、DataNode详解)
  11. Web 设计师的 50 个超便利工具[下]
  12. iOS:NO suitable application records were found.Verify your bundle identifier 'com***'is correct
  13. 全网首发:麒麟平台更新时提示错误:无法解析域名“archive.kylinos.cn”
  14. 印象笔记html预览,超级笔记使用指南 | 印象笔记
  15. java计算机毕业设计中小学生错题管理系统源码+数据库+系统+lw文档+mybatis+运行部署
  16. 怎樣制作线段动画_教程:如何制作一个绘制线条动画
  17. HTML中的 meta 标签
  18. 专升本笔记记载-第七章-无穷级数
  19. jms(jms是什么意思的缩写)
  20. C51学习笔记:基于STC89C52的超声波测距与LCD1602显示

热门文章

  1. 递归处理二叉树总结(附leetcode题)
  2. SDL2源代码分析5:更新纹理(SDL_UpdateTexture())
  3. 我的开源项目:H.264码流分析器
  4. ITU-T G.1081 IPTV性能监测点 (Performance monitoring points for IPTV)
  5. ffmpeg 源代码简单分析 : av_read_frame()
  6. opencv物品定位_使用OpenCV获取零件位置的学习笔记
  7. @transactional可以用在controller层吗_石晶地板可以用在浴室吗?
  8. python 可视化_Python可视化二维高斯分布
  9. linux 镜像 多 网络,Linux内核实现多路镜像流量聚合和复制的方法
  10. Could not resolve placeholder jdbc.driver in string value ${jdbc.driver}