基础部分python学完,咱们可以深入了解下python高阶知识点,让我们一起来学习吧!
1.面向对象进阶
1)元类
1.1.1:python创建类原理
python创建类:
class ObjectCreator:
pass
写了class,python编译器就自动创建了class类了,内部创建的原理:先在内部找属性__metaclass__;__init__等做出相应的处理后再通过type元组来创建:type(类名, 由父类名称组成的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))如:Test2 = type("Test2",(),{}) #定了一个Test2类;
元类就是用来创建这些类(对象)的,元类就是类的类,你可以这样理解为
MyClass = MetaClass() #使用元类创建出一个对象,这个对象称为“类”
MyObject = MyClass() #使用“类”来创建出实例对象
1.1.2:python对象属性__metaclass__的有趣地方
__metaclass__属性:创建类时会先在里面查找是否有__metaclass__属性,有的话就通过这个属性指定的方法创建类;没有就往上级找指到找到,没有找到就通过type方式创建
class Foo(object): __metaclass__ = something… ...省略...
例子:通过__metaclass__属性来控制模块里所有的类的属性都应该是大写形式:
#-*- coding:utf-8 -*- def upper_attr(future_class_name, future_class_parents, future_class_attr): #遍历属性字典,把不是__开头的属性名字变为大写 newAttr = {} for name,value in future_class_attr.items(): if not name.startswith("__"): newAttr[name.upper()] = value #调用type来创建一个类 return type(future_class_name, future_class_parents, newAttr) class Foo(object, metaclass=upper_attr): bar = 'bip' print(hasattr(Foo, 'bar')) print(hasattr(Foo, 'BAR')) f = Foo() print(f.BAR)
2)动态语言
1.2.1定义:
动态语言是高级程序设计语言的一个类别,具体:在运行时可改变其结构的语言。如:新的函数对象代码可以被引进,已有的函数可被清除。
1.2.2 动态给实例绑定属性:仅作用于当前实例
>>> class Person(object): def __init__(self, name = None, age = None): self.name = name self.age = age >>> P = Person("小明", "24") >>> P.sex = "male" #动态给实例绑定属性 >>> P.sex 'male' >>>
1.2.3 动态给类绑定属性:能作用于之后通过类创建的实例
>>> P1 = Person("小丽", "25") >>> P1.sex Traceback (most recent call last): File "<pyshell#21>", line 1, in <module> P1.sex AttributeError: Person instance has no attribute 'sex' >>>> Person.sex = None #给类Person添加一个属性 >>> P1 = Person("小丽", "25") >>> print(P1.sex) #如果P1这个实例对象中没有sex属性的话,那么就会访问它的类属性 None #可以看到没有出现异常 >>>
1.2.4 例子:给实例绑定属性,方法;给类绑定属性,方法,其中给实例绑定方法是需注意P.run = types.MethodType(run, P)
这种形式而不是直接P.run=run
import types #定义了一个类 class Person(object): num = 0 def __init__(self, name = None, age = None): self.name = name self.age = age def eat(self): print("eat food") #定义一个实例方法 def run(self, speed): print("%s在移动, 速度是 %d km/h"%(self.name, speed)) #定义一个类方法 @classmethod def testClass(cls): cls.num = 100 #定义一个静态方法 @staticmethod def testStatic(): print("---static method----") #创建一个实例对象 P = Person("老王", 24) #调用在class中的方法 P.eat() #给这个对象添加实例方法 P.run = types.MethodType(run, P) #调用实例方法 P.run(180) #给Person类绑定类方法 Person.testClass = testClass #调用类方法 print(Person.num) Person.testClass() print(Person.num) #给Person类绑定静态方法 Person.testStatic = testStatic #调用静态方法 Person.testStatic()
1.2.5 运行时删除属性方法
del 对象.属性名;delattr(对象, "属性名")
1.2.6 通过__slots__来限制
在class定义后加上这个限制如:使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的
>>> class Person(object): __slots__ = ("name", "age") >>> P = Person() >>> P.name = "老王" >>> P.age = 20 >>> P.score = 100 Traceback (most recent call last): File "<pyshell#3>", line 1, in <module> AttributeError: Person instance has no attribute 'score' >>>
3)生成器和迭代器
1.3.1 生成器
1.3.1.1 定义
Python一边循环一边计算的机制,成为生成器:generator
1.3.1.2 创建方法
列表生成式改[] 改为 (),生成器保存的是算法
In [15]: L = [ x*2 for x in range(5)] In [16]: L Out[16]: [0, 2, 4, 6, 8] In [17]: G = ( x*2 for x in range(5)) In [18]: G Out[18]: <generator object <genexpr> at 0x7f626c132db0>
1.3.1.3 方法使用
yield:感觉他会将一个值缓存起来next一下就会拿出来
带有 yield 的函数在 Python 中被称之为 generator(生成器);
一般next(含有yield的函数)就能获得值,当拿不到下一个值时,可通过捕获StopIteration异常来处理异常,一般结束数据会保存在这个异常对象value中
例子:
In [30]: def fib(times): ....: n = 0 ....: a,b = 0,1 ....: while n<times: ....: yield b ....: a,b = b,a+b ....: n+=1 ....: return 'done' ....: In [31]: F = fib(5) In [32]: next(F) Out[32]: 1 In [33]: next(F) Out[33]: 1 In [34]: next(F) Out[34]: 2 In [35]: next(F) Out[35]: 3 In [36]: next(F) Out[36]: 5 In [37]: next(F) --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-37-8c2b02b4361a> in <module>() ----> 1 next(F) StopIteration: done
next:获得生成器的下一个值
__next__():跟next()差不多
1.3.2 迭代器
1.3.2.1 定义
迭代是访问集合的一种方式;迭代器对象时可记住遍历位置的对象;迭代器对象从集合第一个位置开始迭代,直到所有元素被访问完结束
1.3.2.2 使用
可迭代对象:能直接作用于for循环的对象称为可迭代对象:Iteratable
判断是否是Iteratable:isinstance([],Iteratable)
迭代器:可被next函数调用并返回下一个值称为Iterator对象
判断是否是Iterator对象:insinstance((x for x in range(10)),Iterator)
1.3.2.3 方法使用
iter():生成器都是 Iterator 对象,但 list 、 dict 、 str 虽然是 Iterable ,却不是 Iterator ,
把 list 、 dict 、 str 等 Iterable 变成 Iterator 可以使用 iter() 函数。
如:isinstance(iter([]), Iterator)
4)装饰器
装饰器在程序开发中会经常用到一个功能,顾名思义:给原有方法封装一个额外方法,这样既能保证原有代码不变,又能扩展新的功能,遵循了“开发封闭”原则,非常完美!
写代码遵循原则:“开放封闭”,封闭已实现的功能代码块;开放对外扩展开发
例子:
def w1(func): def inner(): # 验证1 # 验证2 # 验证3 func() return inner @w1 def f1(): print('f1')
python执行过程:执行w1函数,并将@w1下面函数作为w1参数,即:@w1等价于w1(f1),最终当用户调用f1时,会将f1作为参数传入w1(f1),
之后w1返回做了额外代码处理后将新的f1返回,再执行f1()就是)就是修饰后的实例了,完美!
例子:
#定义函数:完成包裹数据 def makeBold(fn): def wrapped(): return "<b>" + fn() + "</b>" return wrapped #定义函数:完成包裹数据 def makeItalic(fn): def wrapped(): return "<i>" + fn() + "</i>" return wrapped @makeBold def test1(): return "hello world-1" @makeItalic def test2(): return "hello world-2" @makeBold @makeItalic def test3(): return "hello world-3" print(test1())) print(test2())) print(test3())) 运行结果: <b>hello world-1</b> <i>hello world-2</i> <b><i>hello world-3</i></b>