class ObjectName:
def __init__(self,A,B,*args,**kw):
#这是在类初始化定义的时候,对类的一些变量进行赋值
self.paraA = A
self.paraB = B
self.parals = list(args)
self.__dict__.update(kw)#这是通过关键字变量传参,这种传参方式传递的类变量初始化。加入这个方式,就可以实现位置变量和关键字变量传参的混用。
#非集合对象和集合对象的格式化,后者会更复杂些。
#非集合对象,这里是为了区分,把两种类型的参数包含在一起分开演示
def __str__(self):#打印类中的参数
return "{paraA}{paraB}".format(**self.__dict__)
def __repr__(self):#格式化打印类和类参数信息
return “{__class__.__name__}(paraA={paraA!r},paraB={paraB!r})”.format(__class__=self.__class__,**self.__dict__)
#集合对象
def __str__(self):
return ','.join(map(str,self.parals))
def __repr__(self):
return "{__class__.__name__}({paraA!r},{paraB!r},{parals})".format(
__class__=self.__class__,parals=','.join(map(repr,self.parals)),**self.__dict__)
#format是为了获得给定对象的有ige符合要求的字符串表示。__format__传参的两种方式:
someobject.__format__(""):当应用程序中出现format(someobject)或者“{0}".format(someobject)时,会默认以这种方式调用_format_,在这种情况下,会传递一个空字符串,__format__()的返回值会以默认格式表示。
someobject.__format(specification):当应用程序中出现format(someobject,specification)或者“{0:specification}".format(someobject)"时,会默认以这种方式调用_format_(),
ps:“{0!r}".format(),"{0!s}".format()并不会调用format方法,会直接调用repr或者str方法。
def __format__(self,format_spec):
if format_spec == "":
return str(self)
rs= format_spec.replace("%r",self.paraA).replace("%s",self.paraB)
rs = rs.replace("%%","%")
return rs
#python 中有两个哈希库,其中hashlib可以提供密码级别的哈希函数,zlib模块包含两个高效的哈希函数:adler32()和crc32(),对于相对简单的值,我们不使用这些内置的函数,对于复杂或者很大的值可用这些内置函数
hash()函数(以及与其相关联的__hash__()方法)主要被用来创建set,frozenset和dict这些集合类型的键。这些集合利用不可变对象的哈希值来高效地查找集合中的对象。object中默认的__hash__()方法的实现是基于对象内部的ID值生成哈希值,可以用id(object)来查看,如果我们希望包含同样值的不同对象有相同的哈希值,那么就需要修改__hash__()这个方法。
def __hash__(self):
return hash(self.paraA)^hash(self.paraB)
#如果是在封装一个列表,我们可能写一下代码
def __bool__(self):#默认的__bool__方法返回True
return bool(self.parals)
#如果是在扩展一个列表,可能写如下代码
def __bool__(self):
return super().__bool__(self)
#把对象转化为字节,依据不同的参数,bytes()函数的行为也不同
bytes(integer):返回一个不可变的字节对象,这个对象包含了给定数量的0X00值。
bytes(string):这个版本会将字符串编码为字节。其他的编码和一场处理的参数会定义编码的具体过程。
bytes(something):这个版本会调用something.__bytes__()创建字节对象。这里不用编码或者错误处理参数。
基本的object对象没有定义__bytes__(),这一位这所有的类在默认情况下都没有提供__bytes__()方法。
def __bytes_(self):
如果需要定义一个对象底层的字节表示法,最好使用pickle或者json模块。
#python有六个比较 运算符,lt,le,eq,ne,gt,ge(<,<=,==,!=,>,>=),当设计比较运算符时,要考虑两个因素:1:如何比较同一个类的两个对象。2:如何比较不同类的对象。根据不同的需求来设计涉及的比较元素。
#在一些情况下,isinstance()是必需的,尤其是当使用Python内置的类时。但是我们不应该向内置类中追加任何方法函数,而且为了加入一个多态的方法而去使用继承也是不值得的。
def __lt__(self,other):
#显式检查类型
if not isinstance(other, BlackJackCard):
return NotImplemented
return self.rank < other.rank
def __le__(self, other):
#隐式检查类型,try方式有个小小的有点,避免了重复的类名称。
#可以主要关注这种写法,isinstance()方法是python中惯用的
try:
return self.rank <= other.rank
except AttributeError:
return NotImplemented
def __eq__(self,other):
return self.paraA==other.paraA and self.paraB == other.paraB
def _func(self,**)
#以一个下划线开头的函数为类的私有函数。类的私有变量也是如此在变量前面加一个下划线。
def __del__(self): #资源释放为del的一部分实现
print("Removing{__class__.__name__}{id:d}".format(__class__=self.__class__,id=id(self)))
#import gc gc.collect():我们用这方法回收所有定义了__del__()方法但是无法删除的对象
@classmethod
def methodName(cls):
#不需要实例化类即可调用,调用方法为ObjectName.methodName()
文字记录:
1.__new__()方法的一个用途是初始化不可变对象。该方法中允许船舰为初始化的对象。这允许我们在__init__()方法被调用之前先设置对象的属性。由于不可变类的__init__()方法很难重载,因此__new__方法提供了一种扩展这种类的方法。举例为继承float类。new是个天生的静态方法,且不需要@stataicmethod修饰符。
class Float_Units(float):
def __new__(cls,value,unit):
obj = super().__new__(cls,value)#这个很重要,因为float原生类其实只接受一个变量
obj.unit = unit
return obj
new的另一种用途,作为元类型的一部分,主要是为了控制如何创建一个类。
可以直接使用type()作为构造器创建一个新的但是几乎完全没有任何用处的类。>>> use = type("use",(),{})
>>> use
<class '__main__.use'>
>>> use()
<__main__.use object at 0x000001C7F55E1320>
>>> u= use()
>>> dir(u)#这里我们可以看到可以改写的类类预置函数
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
我们几乎总是需要重载__repr__(),__str__()和__format__()这些方法的默认实现不是非常有用。我们不需要重载__bool__()方法,除非我们想自定义集合。
我们常常需要重载比较运算符和__hash__()方法。默认的实现只适合于比较简单不可变对象。我们不一定要重写所有的比较运算符。另外两个较为特殊的方法__new__()和__del__()有更特殊的用途。大多数情况下,使用__new__()来扩展不可变类型。
基本的特殊方法和__init__()方法几乎会出现在我们定义的所有类中,其他的特殊方法则有更特殊的用途。它们分为6个不同的类别。
属性访问:这些特殊方法实现的是表达式中object.attribute的部分,它通常用在一个赋值语句的左操作数以及del语句中。
可调用对象:一个实现了将函数作为参数的特殊方法,很想内置的len()函数
集合:这些特殊方法实现了集合的很多特性,包括sequence[index],mapping[index]和set|set.
数字:这些特殊方法提供了算术运算符和比较运算符。我们可以用这些方法扩展Python支持的数值类型
上下文:有两个特殊方法被我们用来实现可以和with语句一起使用的上下文管理器。
迭代器:有一些特殊方法定义了一个迭代器。没有必要一定要使用这些方法,因为生成器函数很好地实现了这种特性。我们可以了解如何实现自定义的迭代器。
© foreveryoung2014 | Powered by LOFTER