__init__ 初始化方法不要写任何返回语句,他返回的是你的类的实例

特殊属性

__name__ 类和函数的名字

__module__ 类定义所在的模块名

__class__ 对象或类所属的类

__bases__ 类的基类的元组,按列表出现的顺序

__doc__ 类、函数文档字符串,或None

__mro__ class.mro()返回结果保存

__dict__ 类或实例的属性

__dir__方法,查看属性,

返回搜索的内容,尽量多得收集当前模块的信息,可以从一个实例的类以及祖先类上手机信息。内建函数dir()需要用内置的__dir__方法

  1. dir()

  1. 如果对象什么都不指定,是模块对象,收集当前模块的

  2. 如果指定某个对象,收集指定对象相关的属性,包括类以及祖先类的属性。并且去重。

import test2

print(dir())

print(dir(test2))

print(sorted(set(b.__dict.keys()) | set(b.__class__.__dict__.keys()) | set(object.__dict__)))

魔术方法

  1. 创建与销毁

    1. 创建与销毁

init__ __del__

  • python 建立了一个dict存储用来查阅,通过key查阅

用init,添加实例,

  • del与GC回收有关,我们一般不关心。

  1. hash

    1. python将hash用在了可hash类型中,set

    2. 做一个hash散列,hash的时间复杂度是O(1),用在缓存

    3. 缓存的作用是存储备用,再次使用。

    4. buffer的作用是拦河坝,协调生产者和消费者之间速度差的。

    5. hash 冲突,hash值相同

      1. hash值相同的用set来装,是否去重

      2. 关系运算   is    == 分别有什么异同

class A:

   X = 123

   def __init__(self):

       self.y = 5

       pass

   __hash__ = None       # #  TypeError: unhashable type: 'A'

print(hash(A()))

先调 is 再调 ==

hash一定会有冲突,最简单用x % 3做 对x hash。可hash并不代表可去重。如果要去重,得看==

c. bool

  1. 就两条,如果没有这两条,那么就永远为真的。

    1. 可视化

      1. __repr__ ,与__str__几乎不区分,如果缺失了__str__就调用__repr__,如果都没有,就返回object定义,显示内存地址信息。

      2. __str__,str()函数,返回字符串表达,与repr(),__repr__分先后__repr__,repr()对一个对象获取字符串表达,调用__repr__方法返回字符串表达,若__repr__没有定义,就返回object定义,即内存地址信息。

    2. 运算符重载

容器和大小

可调用对象

上下文管理

反射

描述器

其他杂项

__eq__ 判断是不是相同的,逻辑运算符,return结果是bool

__bool__,若没有定义__bool__,就调用__len__

运算符重载根据实际需求使用。

class A:

   def __init__(self, x):

       self.x = x

   def __sub__(self, other):

       return  A(self.x - other.x)

   def __ne__(self, other):

       return self.x != other.x

   def __eq__(self, other):

       return self.x == other.x

   def __lt__(self, other):

       return self.x < other.x

   def __repr__(self):

       return str(self.x)

   def __iadd__(self, other):

       # self.x += other.x

       # return self   a1就地修改

       return A(self.x + other.x)一个新的a1实例      

a1 = A(4)

a2 = A(10)

lst = [a1, a2]

print(sorted(lst))

容器方法

len 与 size的区别,size指的是容器的大小,len是item的数量。并不相等,大小也不一定。

__len__对应内建函数,len()

__getitem__ 用index或者Key,分别对应使用list,dict ,扔进[ ]一个key,返回对应的item或者value,key不存在KeyError

__setitem__ ,[key],设置一个值给这个key

__missing__ ,类default,

__iter__ 必须返回一个迭代器

用魔术方法实现购物车功能

class Color:

   RED = 0

class Item:

   def __init__(self, name, **kwargs):

       self.name = name

       self.__spec = kwargs

   def __repr__(self):

       return "{} = {}".format(self.name, self.__spec.items()))

class Cart:

   def __init__(self):

       self.items = []

   def additem(self, item:Item):

       self.items.append(item)

   def getallitems(self):

       return self.items

   def __getitem__(self, item): # this item is index of items ,Out of range is possible

       return Item(self.items[item])

   def __missing__(self, key): # dict/set key missing ,list can not use this method

       print("key =="key)

   def __setitem__(self, key, value):

       self.items[key] = value

       #self[key] = value 在其他地方可以直接赋值

   def __len__(self):

       return len(self.items)

   def __iter__(self):  # 有了这个方法用户可以直接 for x in cart,而不是for x in cart.items

       return iter(self.items)

   def __add__(self, other):

       if isinstance(other, Item)

       self.items.append(other)

class MyDict(dict): #建一个字典类

pass

可调用对象,类的实例调用,相当于调用实例的__call__

为什么__call__讲一个类的实例调用,call的第一个pos args是self

  • 函数foo,foo(5)等价于foo.__call__(5)

__repr__ = __str__      str调用就等于repr调用,所以让他们

__repr__ = None    让他的返回值是None 就可以实现相等了

上下文管理

with 开启一个上下文环境,在接下来的网络编程中,socket也当文件来用,有上下文

必须是在一个类上去写,并用在实例上。

class Point:

   def __init__(self):

       print('init')

   def __enter__(self): # 维护了文件资源

       print(self.__class__)

       return self

   def __exit__(self, exc_type, exc_val, exc_tb): #

       print(self.__class__.__name__)

p = Point()

import sys

with Point() as f:

   print(p == f)

   print(p is f)

需要给__enter__ return 一个适当的值,给f

exc_type

exc_val

exc_tb 返回类True的话,压制异常

上下文的应用场景

  1. 增强功能

    1. 在代码执行的前后增加代码,类似装饰器的功能。

  2. 资源管理

    1. 文件对象、网络连接、数据库连接等的关闭

  3. 权限验证

    1. 权限验证,在__enter__z中处理

add存在与TImeIT的实例C()的参数中,add函数定义不存在了

contextlib.contextmanager

是一个装饰器,也可以实现上下文管理。对函数有要求,必须是一个生成器函数。

yield虽然在字节码上和return有区别,但是可以把它当成return看。

import contextlib

@contextlib.contextmanager

def foo():

   print('enter')

   yield 3,5 # 必须有yield语句,在yield的发生处切一刀,前后加东西,把yield的返回值放到enter里面,作为返回值。

   print('exit')

   

with foo() as f:

   try:

       raise Exception

   finally:

   

   print(f)

functools @total_ordering ,如果注重效率,就最好不要用。

加上total_ordering用来减少操作,比如定义eq,用total_ordering推演其他比较,如果没有@total无法对进行其他比较。