一、跟实例创建和执行有关的

  __new__、__init__、__call__.

  类加括号调用了__init__方法来创建一个实例对象。这一过程分成了两步: 类调用__new__来创建实例对象,__new__调用__init__来初始化实例对象。

class A:
count = 0
def __init__(self):
print("__init__ has called. 2") def __new__(cls):
print("__new__ has called. 1")
return object.__new__(cls)
def __call__(cls):
print("__call__ has called. 3")
a = A()
a() """
__new__ has called. 1
__init__ has called. 2
__call__ has called. 3
"""

  类的__new__()方法很少通过用户代码定义。如果定义了它,它通常是用原型__new__(cls, *args, **kwargs)编写的。其中args和kwargs与传递给__init__()的参数相同。__new__()始终是一个类方法,接受类对象作为第一个参数。尽管__new__()会创建一个实例,但它不会自动地调用__init__()。实例对象加括号会调用__call__方法,一般作为程序的入口,并且可以在这一步修改实例属性或调用实例方法。

class Obj(object):
def __init__(self, name, price):
self.name = name
self.__price = price def __say(self):
print("{}, {}.".format(self.name, self.__price)) def __call__(self, discount):
self.__price = discount * self.__price
self.__say() apple = Obj("apple", 10.0)
apple(0.8)

二、跟实例属性有关的

  __getattribute__,  __getattr__,  __setattr__, __delattr__、__getitem__、__setitem__、__delitem__、__missing__

  在__init__时,会调用__setattr__初始化实例属性,在__dict__添加键值对。

class Sample:
def __init__(self, name, age):
self.name = name
self.age = age def __setattr__(self, key, value):
print("__setattr__ has called.")
try:
self.__dict__[key] = value
except:
self.__dict__ = {key: value} sam = Sample("Li", 24) # __setattr__ has called.
# __setattr__ has called.

  对实例属性的访问时,

  1.首先执行__getattribute__方法(这又是一个特殊方法),去调用object基类的__getattribute__来查询__dict__里的键值对。如果存在则直接返回,相当于执行了member.__dict__.get(obj),如果不存在则调用__getattr__方法。

  2.__getattr__方法会在实例内存空间中尽可能的搜索该属性值,如果搜索到则直接返回,搜索不到会抛出AttributeError。

  注意下面两段代码的区别:__getattribute__的return只是一个硬编码的字符串而不是属性值,__getattr__的return则是实例的属性值。因此,如果有需求,一般会在__getattr__里写需求代码。

class MemberCounter:
def __init__(self, name, age):
self.name = name
self.age = age def __getattribute__(self, obj):
print("__getattribute__ is called.")
return object.__getattribute__(self, obj) def __getattr__(self, obj):
print("__getattr__ is called.")
return "{} Not assgined.".format(obj)
member = MemberCounter("An", 24) print(member.name)
print("\n------------------\n")
print(member.gender) """
__getattribute__ is called.
An ------------------ __getattribute__ is called.
__getattr__ is called.
gender Not assgined.
"""
class MemberCounter:
def __init__(self, name, age):
self.name = name
self.age = age
def __getattribute__(self, obj):
if obj == "gender":
return "male"
else:
return object.__getattribute__(self, obj) member = MemberCounter("An", 24)
print(member.gender)
member.gender = "female"
print(member.gender)
print(member.__dict__) """
male
male
{'name': 'An', 'age': 24, 'gender': 'female'}
"""

__getattribute__

class MemberCounter:
def __init__(self, name, age):
self.name = name
self.age = age
def __getattr__(self, obj):
if obj == "gender":
return "male"
else:
raise AttributeError member = MemberCounter("An", 24)
print(member.gender)
member.gender = "female"
print(member.gender)
print(member.__dict__) """
male
female
{'name': 'An', 'age': 24, 'gender': 'female'}
"""

__getattr__

  当访问一个属性的时候:

    解释器首先在实例的字典中搜索,
    若找不到则去创建这个实例的类的字典中搜索,
    若还找不到就到类的基类中搜索,
    如果还不找不到最后会尝试调用类的__getattr__方法来获取属性值(若类中定义了该方法的话).
    如果这个过程也失败,则引发AttributeError异常

  在使用member.name = "Wei"和del member.age时,实际上调用了__setattr__和__delattr__。这两个函数没有类似__getattribute__的使用规则。即无论何时给属性赋值,都会调用 __setattr__() 方法;无论何时删除一个属性,都将调用 __delattr__() 方法。

class MemberCounter:
def __init__(self, name, age):
self.name = name
self.age = age def __setattr__(self, old, new):
print("\033[1;36m {} = {} \033[0m has been created.".format(old, new))
object.__setattr__(self, old, new) def __delattr__(self, key):
print("{} is deleted.".format(key))
del self.__dict__[key] def __getattr__(self, item):
return self.__dict__[item] # object.__getattr__(self, item) member = MemberCounter("An", 24)
print(member.__dict__)
del member.age
print(member.__dict__) """
name = An has been created.
age = 24 has been created.
{'name': 'An', 'age': 24}
age is deleted.
{'name': 'An'}
"""
class A:
def __init__(self, *args):
self.name, self.age = args def __getitem__(self, key):
print("__getitem__ has called.")
self.__dict__.get(key, ValueError) def __setitem__(self, key, value):
print("__setitem__ has called.")
self.__dict__.update({key: value}) def __delitem__(self, key):
print("__delitem__ has called.")
del self.__dict__[key] a = A("Li", 27)
print(a.__dict__)
a["name"]
print(a.__dict__)
a["name"] = "Alex"
print(a.__dict__)
del a["age"]
print(a.__dict__) """
{'name': 'Li', 'age': 27}
__getitem__ has called.
{'name': 'Li', 'age': 27}
__setitem__ has called.
{'name': 'Alex', 'age': 27}
__delitem__ has called.
{'name': 'Alex'}
"""
序号 目的 所编写代码 Python 实际调用
1 获取一个计算属性(无条件的) x.my_property x.__getattribute__('my_property')
2 获取一个计算属性(后备) x.my_property x.__getattr__('my_property')
3 设置某属性 x.my_property = value x.__setattr__('my_property', value)
4 删除某属性 del x.my_property x.__delattr__('my_property')
5 列出所有属性和方法 dir(x) x.__dir__()
序号 目的 所编写代码 Python 实际调用
1 通过键来获取值 x[key] x.__getitem__(key)
2 通过键来设置值 x[key] = value x.__setitem__(key, value)
3 删除一个键值对 del x[key] x.__delitem__(key)
4 为缺失键提供默认值 x[nonexistent_key] x.__missing__(nonexistent_key)

三、实例属性的保存格式---__slots__和__dict__

  实例对象通常以字典的形式保存属性, 也即__dict__。这种格式可以被__slots__修改 。下面是从各个python书籍中摘下的关于__slots__描述。

 定义__slots__后,可以在实例上分配的属性名称将被限制为指定的名称,否则将引发AttributeError异常。
 这种限制可以阻止其他人向现有实例添加新属性,解决了用户将值分配给他们无法正确拼写的属性时出现的异常。
 在实际使用时,__slots__从未被当做一种安全的特性来实现。它实际上是对内存和执行速度的一种性能优化。
 使用__slots__的类的实例不再使用字典来存储实例数据。相反,会使用基于数组的更加紧凑的数据结构。
 在会创建大量对象的程序中,使用__slots__可以显著减少内存占用和执行时间。
 __slots__与集成的配合使用需要一定的技巧。如果类继承自使用__slots__的基类,那么它也需要定义__slots__来存储自己的属性(即使它不会添加任何属性)。这样才能充分利用__slots__提供的优势。如果忘记了这一点,派生类的运行速度将更慢,占用的内存也比未在任何类上使用__slots__时多。
 __slots__的使用也可以使代码不必要求实例具有底层__slots__属性。尽管这一点通常不适用于用户代码。但可以编写其他支持对象实用工具库和其他工具。依靠__dict__来调试、序列化对象并执行其他操作。
 __slots__的存在不会对__getattribute__()、__getattr__()、和__setattr__()等方法的调用产生任何影响。因为这些方法应该在类中重新定义。但是,这些方法的默认行为将考虑到__slots__。
 此外,没用必要向__slots__添加方法或特性名称,因为它们存储在类中,而不是存储在每个实例中。
class MemberCounter:
__slots__ = ("name", "age")
# 注意, ()指定存储格式为元组,"name"和"age"严格限制了实例化对象的参数,不可随意增加,但可以删除
def __init__(self, name, age): # 不可再写*args, **kwargs
self.name = name
self.age = age
member = MemberCounter("An", 24, )
# member.__dict__ # 当__slots__被指定时,覆盖了__dict__ print(member.__slots__)
print(member.name, member.age)
# member.gender = "female" 报错
#('name', 'age')
# An 24age"
 如何在定义了__slots__,来储存dict或者list等数据呢?以下面的例子为例:
class Local(object):
__slots__ = ('__dict__', '__list__') def __init__(self, name, age, gender):
object.__setattr__(self, "__dict__", {}) # 注意,__dict__和__list__只是我随意写的,你可以通篇把__dict__改成dict,照样没有关系
object.__setattr__(self, "__list__", []) # 也就是说,__dict__只是一个属性链接,它从__slots__中链接到一个字典对象并提供相关操作 self.name = name # 假定你已经知道self.name = name 实际上式调用了__setattr__方法,也就是自动存到了self.__dict__里
self.age = age
self.gender = gender def __setattr__(self, key, value):
try:
self.__dict__[key] = value
except KeyError:
self.__dict__ = {key: value} def __getattr__(self, name):
try:
return self.__dict__[name]
except KeyError:
raise AttributeError(name) def __delattr__(self, name):
try:
del self.__dict__[name]
except KeyError:
raise AttributeError(name) local = Local("Li", 24, "famle")
print(local.__slots__)
print(local.__dict__)
# 0('__dict__', '__list__')
# {'name': 'Li', 'age': 24, 'gender': 'famle'

四、跟运算有关的

  __eq__(==)、__ge__(>=)、__gt__(>)、__le__ (<=)、__lt__ (<)、__ne__ (!=)、__bool__

  参见: http://old.sebug.net/paper/books/dive-into-python3/special-method-names.html

class A:
def __init__(self, number):
self.number = number def __gt__(self, obj):
print("__gt__ has called.")
return self.number > obj.number def __ge__(self, obj):
print("__ge__ has called.") # 既然执行了这个函数,你可以尽情的在return之前写想写的功能
return self.number >= obj.number a = A(23) # 当你写 23 > 45时,实际等同于 a = int(23), b = int(45); a > b
b = A(45) # 这里A就相当于int
c = A(45) print(a > b)
print(b >= c) """
__gt__ has called.
False
__ge__ has called.
True
"""
序号 目的 所编写代码 Python 实际调用
1 加法 x + y x.__add__(y)
2 减法 x - y x.__sub__(y)
3 乘法 x * y x.__mul__(y)
4 除法 x / y x.__truediv__(y)
5 地板除 x // y x.__floordiv__(y)
6 取模(取余) x % y x.__mod__(y)
7 地板除 & 取模 divmod(x, y) x.__divmod__(y)
8 乘幂 x ** y x.__pow__(y)
9 左位移 x << y x.__lshift__(y)
10 右位移 x >> y x.__rshift__(y)
11 按位 and x & y x.__and__(y)
12 按位 xor x ^ y x.__xor__(y)
13 按位 or x | y x.__or__(y)
此外,还有原地操作:
序号 目的 所编写代码 Python 实际调用
1 原地加法 x += y x.__iadd__(y)
2 原地减法 x -= y x.__isub__(y)
3 原地乘法 x *= y x.__imul__(y)
4 原地除法 x /= y x.__itruediv__(y)
5 原地地板除法 x //= y x.__ifloordiv__(y)
6 原地取模 x %= y x.__imod__(y)
7 原地乘幂 x **= y x.__ipow__(y)
8 原地左位移 x <<= y x.__ilshift__(y)
9 原地右位移 x >>= y x.__irshift__(y)
10 原地按位 and x &= y x.__iand__(y)
11 原地按位 xor x ^= y x.__ixor__(y)
12 原地按位 or x |= y x.__ior__(y)
以及一些自身简单运算:
序号 目的 所编写代码 Python 实际调用
1 负数 -x x.__neg__()
2 正数 +x x.__pos__()
3 绝对值 abs(x) x.__abs__()
4 取反 ~x x.__invert__()
5 复数 complex(x) x.__complex__()
6 整数转换 int(x) x.__int__()
7 浮点数 float(x) x.__float__()
8 四舍五入至最近的整数 round(x) x.__round__()
9 四舍五入至最近的 n 位小数 round(x, n) x.__round__(n)
10 >= x 的最小整数 math.ceil(x) x.__ceil__()
11 <= x的最大整数 math.floor(x) x.__floor__()
12 x 朝向 0 取整 math.trunc(x) x.__trunc__()
13 作为列表索引的数字 a_list[x] a_list[x.__index__()]

五、跟字符串有关的

  __str__、__repr__、__format__、[__bytes__]

  这些都是跟字符串格式和字符串表示有关的特殊方法

class Cls(object):
def __init__(self):
self.name = "alex"
self.age = 27
self.gender = "female"
def __str__(self):
print("__str__ has called.")
return "Str: my name is {}, {}.".format(self.name, self.age)
def __format__(self, special):
print("__format__ has called.")
if special == "":
return self.__str__() # 也可以写成str(self)
for _, v in self.__dict__.items(): # 实际上是{"name": "alex", "age": 27}
special = special.replace("%s", str(v), 1)
return special

  观察下面二段代码打印的结果:

cls = Cls()
str1 = "{:%s, %s, %s}".format(cls)
print("-------------")
print(str1) """
__format__ has called.
-------------
alex, 27, female
"""
cls = Cls()
str2 = format(cls, "my name is %s, %s, %s.")
print("-------------")
print(str2) """
__format__ has called.
-------------
my name is alex, 27, female.
"""

  以上两端代码本质都是一样的,即format和一个字符串匹配,也就是__format__函数传递了special参数(字符串)。

  当format函数没有和字符串匹配,也就是__format__函数没有传入参数special时,会调用__str__函数。

cls = Cls()

str3 = format(cls)
print("-------------")
print(str3) """
__format__ has called.
__str__ has called.
-------------
Str: my name is alex, 27.
"""

  str(cls)调用了__str__方法。str(cls)调用__str__方法, string.format(cls)和format(cls)调用__format__方法。

cls = Cls()
print(str(cls)) """
__str__ has called.
Str: my name is alex, 27.
"""

  再来看__str__和__repr__的区别和联系。当__str__存在时,print(obj)和str(obj)实际调用了__str__方法;当__str__不存在时,就会调用__repr__。但是当定义了__repr__时,obj本身会返回一个"合法"的字符串表达式,而不再返回一个描述符<'__main__.A object at XXX>,当然这个描述符也可以被__str__修改,只是会被__repr__覆盖。

class A:
def __str__(self):
print("__str__ has called.")
return self.__class__.__name__ + "__str__" a = A() a # <__main__.A at 0x110a764e0>
print(a)
# __str__ has called.
# A__str__ str(a)
# __str__ has called.
# A__str__
class A:
def __repr__(self):
print("__repr__ has called.")
return self.__class__.__name__ + "__repr__"
a = A() a
#__repr__ has called.
#A__repr__ print(a)
#__repr__ has called.
#A__repr__ str(a)
#__repr__ has called.
#A__repr__
class A:
def __str__(self):
print("__str__ has called.")
return self.__class__.__name__ + "__str__" def __repr__(self):
print("__repr__ has called.")
return self.__class__.__name__ + "__repr__"
a = A() a #__repr__ has called.
#A__repr__ print(a)
#__str__ has called.
#A__str__ str(a)
#__str__ has called.
#'A__str__'
序号 目的 所编写代码 Python 实际调用
1 初始化一个实例 x = MyClass() x.__init__()
2 字符串的“官方”表现形式 repr(x) x.__repr__()
3 字符串的“非正式”值 str(x) x.__str__()
4 字节数组的“非正式”值 bytes(x) x.__bytes__()
5 格式化字符串的值 format(x, format_spec) x.__format__(format_spec)

  通常__str__()__repr__()代码都是一样的,所以会这么写:

class Student(object):
def __init__(self, name):
self.name = name
def __str__(self):
return 'Student object (name=%s)' % self.name
__repr__ = __str__

六、跟迭代器有关的

序号 目的 所编写代码 Python 实际调用
1 遍历某个序列 iter(seq) seq.__iter__()
2 从迭代器中获取下一个值 next(seq) seq.__next__()
3 按逆序创建一个迭代器 reversed(seq) seq.__reversed__()

  iter内置函数对应的特殊方法是__iter_,它把一个序列变成迭代器。

class Iter:
def __init__(self, lis):
self.iterate = lis
def __iter__(self):
for v in self.iterate:
print("__iter__ has called.")
yield v a = Iter(list(range(5)))
b = iter(a) print(next(b))
print(next(b)) """
__iter__ has called.
0
__iter__ has called.
1 """

  next内置函数对应的特殊方法是__iter_,对迭代器进行迭代(惰性行)。

class Iter:
count = 0
def __init__(self, lis):
self.iterate = lis
def __next__(self):
print("__next__ has called.")
try:
value = self.iterate[Iter.count]
Iter.count += 1
except StopIteration:
exit()
return value a = Iter(list(range(5))) print(next(a))
print(next(a)) """
__next__ has called.
0
__next__ has called.
1 """

  至此我们已了解了绝大部分特殊方法,在python中,类对象的顶层是type类。下面是object类和type类的源码。它们的源码是底层实现的。

class object:
""" The most base type """
def __delattr__(self, *args, **kwargs): # real signature unknown
""" Implement delattr(self, name). """
pass def __dir__(self): # real signature unknown; restored from __doc__
"""
__dir__() -> list
default dir() implementation
"""
return [] def __eq__(self, *args, **kwargs): # real signature unknown
""" Return self==value. """
pass def __format__(self, *args, **kwargs): # real signature unknown
""" default object formatter """
pass def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __ge__(self, *args, **kwargs): # real signature unknown
""" Return self>=value. """
pass def __gt__(self, *args, **kwargs): # real signature unknown
""" Return self>value. """
pass def __hash__(self, *args, **kwargs): # real signature unknown
""" Return hash(self). """
pass def __init_subclass__(self, *args, **kwargs): # real signature unknown
"""
This method is called when a class is subclassed. The default implementation does nothing. It may be
overridden to extend subclasses.
"""
pass def __init__(self): # known special case of object.__init__
""" Initialize self. See help(type(self)) for accurate signature. """
pass def __le__(self, *args, **kwargs): # real signature unknown
""" Return self<=value. """
pass def __lt__(self, *args, **kwargs): # real signature unknown
""" Return self<value. """
pass @staticmethod # known case of __new__
def __new__(cls, *more): # known special case of object.__new__
""" Create and return a new object. See help(type) for accurate signature. """
pass def __ne__(self, *args, **kwargs): # real signature unknown
""" Return self!=value. """
pass def __reduce_ex__(self, *args, **kwargs): # real signature unknown
""" helper for pickle """
pass def __reduce__(self, *args, **kwargs): # real signature unknown
""" helper for pickle """
pass def __repr__(self, *args, **kwargs): # real signature unknown
""" Return repr(self). """
pass def __setattr__(self, *args, **kwargs): # real signature unknown
""" Implement setattr(self, name, value). """
pass def __sizeof__(self): # real signature unknown; restored from __doc__
"""
__sizeof__() -> int
size of object in memory, in bytes
"""
return 0 def __str__(self, *args, **kwargs): # real signature unknown
""" Return str(self). """
pass @classmethod # known case
def __subclasshook__(cls, subclass): # known special case of object.__subclasshook__
"""
Abstract classes can override this to customize issubclass(). This is invoked early on by abc.ABCMeta.__subclasscheck__().
It should return True, False or NotImplemented. If it returns
NotImplemented, the normal algorithm is used. Otherwise, it
overrides the normal algorithm (and the outcome is cached).
"""
pass __class__ = None # (!) forward: type, real value is ''
__dict__ = {}
__doc__ = ''
__module__ = ''

object

class type(object):
"""
type(object_or_name, bases, dict)
type(object) -> the object's type
type(name, bases, dict) -> a new type
"""
def mro(self): # real signature unknown; restored from __doc__
"""
mro() -> list
return a type's method resolution order
"""
return [] def __call__(self, *args, **kwargs): # real signature unknown
""" Call self as a function. """
pass def __delattr__(self, *args, **kwargs): # real signature unknown
""" Implement delattr(self, name). """
pass def __dir__(self): # real signature unknown; restored from __doc__
"""
__dir__() -> list
specialized __dir__ implementation for types
"""
return [] def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass def __init__(cls, what, bases=None, dict=None): # known special case of type.__init__
"""
type(object_or_name, bases, dict)
type(object) -> the object's type
type(name, bases, dict) -> a new type
# (copied from class doc)
"""
pass def __instancecheck__(self): # real signature unknown; restored from __doc__
"""
__instancecheck__() -> bool
check if an object is an instance
"""
return False @staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass def __prepare__(self): # real signature unknown; restored from __doc__
"""
__prepare__() -> dict
used to create the namespace for the class statement
"""
return {} def __repr__(self, *args, **kwargs): # real signature unknown
""" Return repr(self). """
pass def __setattr__(self, *args, **kwargs): # real signature unknown
""" Implement setattr(self, name, value). """
pass def __sizeof__(self): # real signature unknown; restored from __doc__
"""
__sizeof__() -> int
return memory consumption of the type object
"""
return 0 def __subclasscheck__(self): # real signature unknown; restored from __doc__
"""
__subclasscheck__() -> bool
check if a class is a subclass
"""
return False def __subclasses__(self): # real signature unknown; restored from __doc__
""" __subclasses__() -> list of immediate subclasses """
return [] __abstractmethods__ = property(lambda self: object(), lambda self, v: None, lambda self: None) # default __bases__ = (
object,
)
__base__ = object
__basicsize__ = 864
__dictoffset__ = 264
__dict__ = None # (!) real value is ''
__flags__ = 2148291584
__itemsize__ = 40
__mro__ = (
None, # (!) forward: type, real value is ''
object,
)
__name__ = 'type'
__qualname__ = 'type'
__text_signature__ = None
__weakrefoffset__ = 368

type

python(六):面型对象--类的特殊方法的更多相关文章

  1. python语言中threading.Thread类的使用方法

    1. 编程语言里面的任务和线程是很重要的一个功能.在python里面,线程的创建有两种方式,其一使用Thread类创建 # 导入Python标准库中的Thread模块 from threading i ...

  2. Python的程序结构[2] -> 类/Class[2] -> 方法解析顺序 MRO

    方法解析顺序 / MRO (Method Resolution Order) 关于方法解析顺序(MRO)的详细内容可以参考文末链接,这里主要对 MRO 进行简要的总结说明以及一些练习示例. 经典类和新 ...

  3. Python漫谈-比较运算符和类的神奇方法

    昨天遇到一个Python问题,今天好奇试了一下 >>> a = {1:23,'ab':56} >>> b = {2:22,'ab':57} >>> ...

  4. python 面向对象专题(六):元类type、反射、函数与类的区别、特殊的双下方法

    目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3. 函数与类的区别 4. 特殊的双下方法 1. 元类type type:获取对象 ...

  5. python的异常处理及异常类定义

    python的异常处理语法和大多数语言相似: try: try块的语句... except exceptiontype1 as var:#使用as语句获得本次捕获到的异常的实例var except块语 ...

  6. python 面向对象之封装与类与对象

    封装 一,引子 从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小猫,小狗,小王八,小老虎一起装进麻袋,然后把麻袋封上口子.照这种逻辑看,封装='隐藏',这种理解是相当片面的 二,先看如何隐藏 在 ...

  7. python的类和对象——类成员番外篇

    学完了面向对象的三大特性,已经get了所有屌丝技能的我们也当一回文艺小青年,来看看类的成员和成员修饰符. 今天‘三’这个数字好亲和~~~类成员可以分为三类:字段.方法和属性 一.字段 首先我们来看看字 ...

  8. [译]Selenium Python文档:六、页面对象

    本章是介绍页面对象设计模式的教程.一个页面对象代表了web应用用户接口的一片区域,你的测试代码将与之交互的. 使用页面对象模式的好处: 可以创建在多个测试样例中都可使用的可重用代码 减少重复性代码 如 ...

  9. Python StringIO与BytesIO、类文件对象

    StringIO与BytesIO StringIO与BytesIO.类文件对象的用途,应用场景,优.缺点. StringIO StringIO 是io 模块中的类,在内存中开辟的一个文本模式的buff ...

随机推荐

  1. Bigdecimal: Non-terminating decimal expansion; no exact representable decimal result.

    做除法没有指定保留小数点后几位,就会抛出此异常. 因为会除不尽 Non-terminating decimal expansion; no exact representable decimal re ...

  2. 关于JNDI那点事

    一.JNDI是什么? JNDI--Java 命名和目录接口(Java Naming and Directory Interface),是一组在Java应用中访问命名和目录服务的API. 二.JNDI好 ...

  3. max_spare_servers到底是个什么意思?

    pm.max_children=500pm.start_servers=280pm.min_spare_servers=50pm.max_spare_servers=500 把max_spare_se ...

  4. SpringSecurity——基于Spring、SpringMVC和MyBatis自定义SpringSecurity权限认证规则

    本文转自:https://www.cnblogs.com/weilu2/p/springsecurity_custom_decision_metadata.html 本文在SpringMVC和MyBa ...

  5. Go连接MySql数据库Error 1040: Too many connections错误解决

    原文:https://my.oschina.net/waknow/blog/205654 摘要: 使用Go链接数据库时,由于连接释放不当会在一段时间以后产生too many connections的错 ...

  6. pahlcon:cookies设置

    非加密方式(简单,但不推荐) 步骤 1 在全局容器中加入Cookie: $di->set('cookies', function () { $cookies = new \Phalcon\Htt ...

  7. 【原创】Centos 7利用软件Raid搭建ISCSI过程

    测试机器安装了4块2T硬盘,一块320G硬盘,利用320G硬盘安装CentOS 7系统,在CentOS 7系统上利用4块2T硬盘组建Raid 0,再配置iSCSI存储.注意,本文中的RAID指的是软R ...

  8. 1-27 awk 基本使用

    大纲: 色彩: awk基本使用 ##################################################### 一.色彩:shell中,设置输出文本色彩(前景色,背景色) ...

  9. Ansible 开发调试 之【模块调试】

    本地调试 需要安装jinja2 库 yum -y install python-jinja2 使用官方提供的测试脚本调试 git clone git://github.com/ansible/ansi ...

  10. Bootstrap 可视化布局--拖拽后弹窗进行编辑

    Bootstrap 可视化布局--拖拽后弹窗进行编辑 最近后台想一个需求,使用可视化布局-中文 | en中拖拽表格后,弹窗进行编辑,保存下载后在后台生成pdf格式. 奈何各种问题不断,使用 jquer ...