各种魔法方法

  • `__init__` 在 类名() 触发它的执行
  • `__setattr__` :在 对象.属性=值 会触发它的执行
  • `__getattr__` :在 对象.属性 获取值会触发它的执行
  • `__delattr__ ` :在 del 对象.属性 会触发它的执行
  • 多态性的使用
  • `__getattribute__`无论属性在对象中是否存在,都先触发__getattribute__的执行
  • `__setitem__`和`__getitem__`和`__delitem__`
  • `__format__` 调用format(对象,'字符串格式')触发
  • `__del__` 调用del功能时触发
  • `__doc__`查看类的注释信息
  • `__call__` 对象() 触发执行
  • `__init__`和 `__new__`
  • `__module__` 和 `__class__`
  • `__str__` 和 `__repr__`
  • `__slots__` 和 `__dict__`
  • `__all__` 导入模块时可以限制使用的属性
  • `__iter__` 和 `__next__`
  • `__len__`
  • `__hash__`
  • ` __eq__`
  • `__enter__` 和 `__exit__` 上下文管理器
  • 描述符
    • `__get__`(),`__set__`(),`__delete__`() 的应用
    • 描述符的种类
    • 对象.属性:取值的顺序
    • 赋值类型限制
    • 复制类型限制 装饰器
    • 自己定制一个property装饰器
    • 自己定制一个classmethod装饰器
    • 自己定制一个staticmethod装饰器

__init__ 在 类名() 触发它的执行

class Person:def __init__(self, name, age):self.name = nameself.age = ageprint('执行....')p = Person('xio', 18)  # 执行....

__setattr__ :在 对象.属性=值 会触发它的执行

class Person:def __setattr__(self, key, value):print('我执行了')print(key)print(value)# self.key=value  # 根本不对# setattr(self,key,value)  # 本质会调用对象自己的__setattr__ ,出递归,报错object.__setattr__(self, key, value)  # 把key,value放到了object里p = Person()
p.name = 'xio'
'''
我执行了
name
xio
'''

__getattr__ :在 对象.属性 获取值会触发它的执行

class Person:def __getattr__(self, item):  # 当属性不在对象中,会触发它的执行print('我执行了')p = Person()
print(p.age)
'''
我执行了
None
'''
# 如果类里面有age属性那就不会触发__getattr__,而直接打印age的值

__delattr__ :在 del 对象.属性 会触发它的执行

class Person:def __delattr__(self, item):print('删除会触发我')p = Person()
del p.name  # 删除会触发我
# 不管属性存不存在 都会del都会触发__delattr__运行

多态性的使用

ll = [1, 2, 3]
dic = {'name': 'lqz', 'age': 19}
print(len(ll))  # 面向对象多态性的使用
print(len(dic))  # 面向对象多态性的使用
# # len内部调用了ll.__len__()
# # len内部调用了dic.__len__()# setattr(对象,key,value)
# 内部:对象.__setattr__(key,value)
# 保证对象必须要有__setattr__,所有类的基类,object中有__setattr__dix = {'name': 'xio'}
print(dix['name'])  # xio
print(dix.name)  # 报错

__getattribute__无论属性在对象中是否存在,都先触发__getattribute__的执行

### 无论属性在对象中是否存在,都先触发__getattribute__的执行(用的比较少)
class Person:name = 'xio'# 属性不存在,才触发def __getattr__(self, item):print('getattr触发了')def __getattribute__(self, item):print('__getattribute__触发了')p = Person()
print(p.name)
'''
__getattribute__触发了
None
'''# 对象.属性 调用顺序   先执行:__getattribute__----》类的名称空间----》__getattr__(本质是去对象自己的名称空间拿东西)
# 对象.属性的查找顺序#当getattribute与getattr同时存在,只会执行getattrbute,除非getattribute在执行过程中抛出异常AttributeError

__setitem____getitem____delitem__

# __getitem__: 通过中括号取值触发它的执行
# __setitem__:通过中括号赋值,触发它的执行
# __delitem__:通过中括号删除值,触发它的执行class Person:def __getitem__(self, item):print('__getitem__执行')def __setitem__(self, key, value):print('__setitem__执行')def __delitem__(self, key):print('__delitem__执行')p = Person()
p['name'] = 'lqz'  # __setitem__执行
p['name']  # __getitem__执行
del p['age']  # __delitem__执行

__format__ 调用format(对象,‘字符串格式’)触发

# 一 字符串格式
s = '我的名字是:%s' % 'xio'
print(s)  # 我的名字是:xio# 字符串的format方法支持的格式化方式res = '我的名字是{},年龄是{}'.format('xio', 18)
res1 = '我的名字是{0},年龄是{1}'.format('xio', 18)ll = ['xio', 19]
l2 = ['男']
res = '我的名字是{0[0]},年龄是{0[1]},性别是{1[0]}'.format(ll, l2)
dic = {'name': 'xio', 'age': 19, 'sex': '男'}
res1 = '我的名字是{name},年龄是{age},性别是{sex}'.format(**dic)class Person:def __init__(self):self.name = 'xio'self.age = 19self.sex = '男'p = Person()
# res='我的名字是{0.name},年龄是{0.age},性别是{0.sex}'.format(p)
res = '我的名字是{obj.name},年龄是{obj.age},性别是{obj.sex}'.format(obj=p)
print(res)  # 我的名字是xio,年龄是19,性别是男
  • 对象的__format__ 调用format(对象,‘字符串格式’)触发
class Person():__dic = {'n-a': '名字是:{obj.name}-----年龄是:{obj.age}','n:a': '名字是:{obj.name}:::::年龄是:{obj.age}','n/a': '名字是:{obj.name}/年龄是:{obj.age}',}def __init__(self, name, age, sex):self.name = nameself.sex = sexself.age = agedef __format__(self, format_spec):# print(format_spec)if format_spec and format_spec in self.__dic:s = self.__dic[format_spec]else:s = self.__dic['n-a']return s.format(obj=self)p = Person('xio', 18, '男')res = format(p)  # 名字是:xio-----年龄是:18
res = format(p, 'n-a')  # 名字是:xio-----年龄是:18
res = format(p, 'n/a')  # 名字是:xio/年龄是:18
res = format(p, 'n:a')  # 名字是:xio:::::年龄是:18
print(res)

__del__ 调用del功能时触发

class Person:def __init__(self, name, age):self.name = nameself.age = agedef __del__(self):# 资源清理工作print('xxxx')p = Person('xio',18)
del p
# xxxx
class ProcessFile:def __init__(self,name):self.f=open(name,'wt',encoding='utf-8')def write(self,s):self.f.write(s)def close(self):self.f.close()def __del__(self):# 请理性的工作self.f.close()p=ProcessFile('a.txt')
p.write('xxxx')
p.close()# del p  系统结束后会自动运行,然后触发__del__方法

__doc__查看类的注释信息

class Person:'''类的提示信息,注释'''passprint(Person.__doc__)  # 类的提示信息,注释
# 查看不了父类的

__call__ 对象() 触发执行

# 不支持对象()调用
class Person:def __init__(self, name):self.name = namep = Person('xio')
p()
# 支持
class Person:def __init__(self, name):self.name = namedef __call__(self, *args, **kwargs):print('我执行了')p = Person('xio')
p()  # 触发__call__的执行,里面有什么,就会执行什么
# 1 后期flask源码中使用了它# from flask import Flask
# print(Flask.__doc__)
# # 类实例化得到一个对象
# # 当有一个请求过来,内部会执行 app()
# # Flask类的 __call__是整个flask项目的入口
# app=Flask(__name__)# 2 一切皆对象
# Person 类,也是一个对象   Person()----->触发生成Person类的类的__call__,不是触发Person的__call__
# Person类生成的对象 --->p()--->触发Person的__call__

__init____new__

# __init__  对象初始化调用   类() 会触发
# __new__   对象生成        类() 会触发,是在__init__之前触发class Person:def __init__(self, name):print('我执行了,我是__init__')self.name = namedef __new__(cls, *args, **kwargs):print('我出生了')# __new__内部会触发 self.__init__的执行obj = object.__new__(cls)# return {'name':'l1z'}  # 不会触发__init__return obj  # 触发 __init__p = Person('xio')  # 触发__new__,返回 obj 对象print(p)
'''
我出生了
我执行了,我是__init__
<__main__.Person object at 0x7f8f22789f10>
'''
'''
Person()---->本质触发的是__new__,因为__new__返回什么对象就是什么
__init__是初始化方法,在__new__后执行的__new__:创造出一个空对象,没有初始化
__init__:创造完空对象后,再触发它,完成初始化'''
# 总结:类实例化得到对象,本质是在执行类的 __new__,返回什么对象,p拿到的就是什么对象,在__new__内部,调用了__init__
# 如果__new__没有返回值,print(p)返回的就是None

__module____class__

# __class__   对象.__class__   查看对象的类class Animal:passclass Person(Animal):passprint(Person.__bases__)  # (<class '__main__.Animal'>,)  # 查看父类
p = Person()print(p.__class__)  # <class '__main__.Person'>
# __modules__:看对象属于哪个模块(用的很少,了解即可)from a import Cobj = C()class Person():passp = Person()
print(obj.__module__)  # a
print(p.__module__)  # __main__

__str____repr__

# __str__ : print(对象) 触发对象的 __str__,优先触发 __str__
# __repr__: 再命令窗口中直接写 p 触发 __repr__class Person:def __init__(self, name):self.name = namedef __str__(self):  # 会经常写return self.name + 'ddddd'def __repr__(self):  # 写的少return self.namep = Person('xio')
print(p)

__slots____dict__

# __slots__:控制对象可以使用的属性
# __dict__: 对象属性# slots是一个类变量,变量值可以是列表,元祖,或者可迭代对象,也可以是一个字符串(意味着所有实例只有一个数据属性)
# 使用点来访问属性本质就是在访问类或者对象的dict属性字典(类的字典是共享的,而每个实例的是独立的)#  一旦使用了slots,对象就没有自己的dict了
#  slots的实际应用场景
# 1 限制对象的属性
# 2 节省内存(对象很多,但属性很少,使用它,节省内存)# 一个类,每生成一个对象,对象有自己的dict,如果对象自身有很多属性,(对象越多)这样占用的内存空间就很多
# 使用了slots后,所有的对象,都使用类名称空间中的属性,对象越多,越节省内存# 字典会占用大量内存,如果你有一个属性很少的类,但是有很多实例,为了节省内存可以使用slots取代实例的dictclass Person:__slots__ = ['name', 'age']  # 对象只拥有name和age属性,没有xxx属性def __init__(self, name, age, xxx):self.name = nameself.age = age# self.xxx = xxxdef __str__(self):return self.namep1 = Person('xio', 19, 'xxx')
p2 = Person('json', 18, 'xxx')# 对象自己没有名称空间了,统一全用类的名称空间
# print(p1.__dict__)  # AttributeError: 'Person' object has no attribute '__dict__'
# print(p2.__dict__)  # AttributeError: 'Person' object has no attribute '__dict__'
# print(p1.__slots__)  # ['name', 'age']
# print(p2.__slots__)  # ['name', 'age']
print(p1.name)  # xio  # 调用的是类里面的属性
print(p1.age)  # 19  # 调用的是类里面的属性print(Person.__dict__)
# {'__module__': '__main__', '__slots__': ['name', 'age'], '__init__': <function Person.__init__ at 0x7fe5eaac1a60>, '__str__': <function Person.__str__ at 0x7fe5ead864c0>, 'age': <member 'age' of 'Person' objects>, 'name': <member 'name' of 'Person' objects>, '__doc__': None}# 总结
'''
## slots的实际应用场景
# 1 限制对象的属性
# 2 节省内存(对象很多,但属性很少,使用它,节省内存)'''

__all__ 导入模块时可以限制使用的属性

# __all__:使用from  a import  *导入模块时,限制能够使用的属性
# __all__=['age','name']'''a.py
__all__ = ['age', 'name']
age = 10
name = 'xio'
sex = '男'
'''from a import *print(age)  # 10
print(name)  # xio
print(sex)  # NameError: name 'sex' is not defined # 调不到

__iter____next__

 -可迭代对象:对象有__iter__方法,这个对象就是一个可迭代对象-for循环本质就是在循环可迭代对象-for i in 对象(必须是可迭代对象)-for循环的本质:先调用对象的__iter__得到一个迭代器对象,然后调用迭代器       对象的__next__ 方法,每次获得一个值(next这种获取值的方式不依赖于索引,又叫迭代循环)-迭代器对象:-既有__iter__又有__next__的对象,就是迭代器对象-迭代器对象一定是可迭代对象-定制自己的可迭代对象-重写类中的__iter__和__next__-让它支持for循环直接循环(做出一种不依赖于索引取值的方式)-不停的return 值,当要停下时,抛出异常
# 0 链式调用(跟语言无关)
# f.test().test2().test3()  # java,js:中广泛应用,设计程序的模式# 如何实现支持链式调用的对象
class Foo:def __init__(self, name, age, sex):self.name = nameself.age = ageself.sex = sexdef print_name(self):print(self.name)return selfdef print_age(self):print(self.age)return selfdef print_sex(self):print(self.sex)return selff = Foo('xio', 16, '男')
f.print_name()
f.print_sex()
f.print_age()# 链式调用
f.print_name().print_sex().print_age()  # 每次用.调用完得到的都是return的返回值
  • __iter____next__ 的应用
# 1 给一个类,重写__iter__,__next__
class Foo:def __init__(self):self.__x = 1def __iter__(self):return selfdef __next__(self):self.__x += 1return self.__xf = Foo()  # f就是一个可迭代对象,所以他就能够被for 循环for i in f:  # f.__iter__()----->每循环一次,调用一下 f.__next__()print(i)
# 自定制可迭代对象(自己写的对象,可以迭代,可以被for循环)
# 加入异常,for循环该对象,可以停止# 实现自己的range
class MyRange:def __init__(self, start, end, step=1):self.__start = startself.__end = endself.__step = stepdef __iter__(self):return selfdef __next__(self):self.__start += self.__stepif self.__start >= self.__end:raise StopIteration('')  # 抛出一个异常,程序就结束了return self.__startfor i in MyRange(1, 20):print(i)
  • 练习题:斐波那契数列(通过__iter__和__next__实现)
class Fib:def __init__(self, count):self.start = 0self.second = 1self.count = countdef __iter__(self):return selfdef __next__(self):self.start, self.second = self.second, self.start + self.secondif self.start >= self.count:raise StopIteration()return self.startfor i in Fib(100):print(i)

__len__

# __len__:计算对象长度,返回几,len(对象),结果就是几class Foo:def __init__(self, name, age):self.name = nameself.age = agedef __len__(self):# return len(self.__dict__)return 5f = Foo('xio', 19)
f.hobby = 'xxx'print(len(f))  # 5

__hash__

# __hash__   ,hash(对象)触发执行,返回什么就是什么
# 如果一个对象不可hash,通过重写 __hash__让它变得可hash# 可变类型,不可hash
# 不可变类型,可以hash# l = ['1', 3, 54, 56]
# dic = {'name': 'lqz'}
#
# a = 10
#
# print(hash(a))
# # print(hash(dic))
# print(hash(l))#
class Foo:def __init__(self):self.name = 'lqz'self.l = ['1', 3, 4]def __hash__(self):return hash(self.name)f = Foo()
print(hash(f))

__eq__

# 两个对象 == 比较的时候,触发 __eq__的执行,在内部,自定制比较规则即可# a=10
#
# b=100
# print(a==b)
#
# l=[1,3,4]
# l2=[1,3,4]
# print(l==l2)
#
# print(a==l2)  # 注意,可以通过 == 比较class Foo:def __str__(self):return self.namedef __init__(self, name):self.name = namedef __eq__(self, other):print(self)  # xioprint(other)  # json# 自己定制比较规则if self.name == other.name:return Trueelse:return Falsef1 = Foo('xio')
f1.age = 999f2 = Foo('json')
f2.age = 888
print(f1 == f2)  # False
print(f1 is f2)  # 不会触发__eq__

__enter____exit__ 上下文管理器

# with open() as f:
# with 上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明enter和exit方法
'''a.txt
hello word
'''# 自定制一个open,打开文件
class Open:def __init__(self, path, mod='rt', encoding='utf-8'):self.f = open(path, mod, encoding=encoding)def __enter__(self):return self.fdef __exit__(self, exc_type, exc_val, exc_tb):  # with结束后运行# 如果exc_tpye 不为空,表示with上下文内部出了错误,处理错误if exc_type:print('程序出错了,但是我处理好了,继续执行就好了')print(exc_val)return True# 没有错误,正常结束,资源清理工作(关闭文件)print('文件关闭了,放心好了')self.f.close()# def read(self):#     return self.f.read()# 后期会使用with ,处理数据库链接,redis链接with Open('a.txt', 'r', encoding='utf-8') as f:res = f.read()  # res的值是__enter__ return出来的print(res)  # hello word'''
优点:
使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无须手动干预
在需要管理一些资源比如文件,网络连接和锁的编程环境中,可以在exit中定制自动释放资源的机制,你无须再去关系这个问题,这将大有用处
'''

描述符

__get__(),__set__(),__delete__() 的应用

class Str():def __get__(self, instance, owner):print(self)  # <__main__.Str object at 0x00000220483C4670>  # Str的对象print(instance)  # <__main__.People object at 0x00000220483C4C40>  # People的对象print(owner)  # <class '__main__.People'>  # People这个类def __set__(self, instance, value):print(self)  # <__main__.Str object at 0x00000220483C4670>  # Str的对象print(instance)  # <__main__.People object at 0x00000220483C4C40>  # People的对象print(value)  # xiodef __delete__(self, instance):print(self)  # <__main__.Str object at 0x00000220483C4670>  # Str的对象print(instance)  # <__main__.People object at 0x00000220483C4C40>  # People的对象class People:name = Str()# 只要类属性被描述符类代理了,以后使用   对象.属性   ,就会触发描述符类的__set__,__get__,__delete__,# 并且只在类名称空间有,对象名称空间就没有该属性了def __init__(self):  # name被Str类代理self.name = 'xio'  # 赋值,就会触发描述符类的__set__方法p = People()  # 触发__init__---> 触发self.name = 'xio'---> 触发__set__
p.name  # 触发name = Str()---> 触发__get__
del p.name  # 触发name = Str()---> 触发__delete__

描述符的种类

  • 数据描述符:至少有__get____set__
class Str:def __get__(self, instance, owner):passdef __set__(self, instance, value):passdef __delete__(self, instance):pass
  • 非数据描述符:没有实现__set__
class Str1:def __get__(self, instance, owner):passdef __delete__(self, instance):pass

对象.属性:取值的顺序

# 描述符本身应该定义成新式类,被代理的类也应该是新式类
# 必须把描述符定义成这个类的类属性,不能为定义到构造函数中
# 要严格遵循该优先级,优先级由高到底分别是
# 1.类属性
# 2.数据描述符
# 3.实例属性    (对象属性)
# 4.非数据描述符
# 5.找不到的属性触发getattr()

赋值类型限制

# python是弱类型语言,即参数的赋值没有类型限制,下面我们通过描述符机制来实现类型限制功能class Typed:def __init__(self, name, type_key):self.name = nameself.type_key = type_keydef __get__(self, instance, owner):return instance.__dict__[self.name]def __set__(self, instance, value):if isinstance(value, self.type_key):instance.__dict__[self.name] = value  # 放到对象中去了else:print('类型不合法,不能放')def __delete__(self, instance):print(instance)print(f'已删除 {instance.__dict__}')class People:name = Typed('name', str)age = Typed('age', int)salary = Typed('salary', float)is_marrey = Typed('is_marrey', bool)p = People()
p.name = 'xio'  # 触发name = Typed('name', str)---> 触发__set__把name='xio'保存到People对象p里
print(p.name)  # 触发name = Typed('name', str)---> 触发__get__把People对象p里的name取出来
del p.name  # 触发name = Typed('name', str)---> 触发__delete__把People对象p.__dict__里的{'name': 'xio'}删除print(People.__dict__)
'''
{'__module__': '__main__', 'name': <__main__.Typed object at 0x00000161086A4670>, 'age': <__main__.Typed object at 0x00000161086E9340>, 'salary': <__main__.Typed object at 0x00000161086E93D0>, 'is_marrey': <__main__.Typed object at 0x00000161086E9370>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}
'''
# name、age、都对应的是Typed的实例对象

复制类型限制 装饰器

class Typed:def __init__(self, name, type_key):self.name = nameself.type_key = type_keydef __get__(self, instance, owner):return instance.__dict__[self.name]def __set__(self, instance, value):if isinstance(value, self.type_key):instance.__dict__[self.name] = value  # 放到对象中去了else:print('类型不合法,不能放')def __delete__(self, instance):print(instance)print('delete')def typeassert(**kwargs):def decorate(cls):# print('类的装饰器开始运行啦------>', kwargs)for key, value in kwargs.items():# print(key)# print(value)# cls.__dict__[key]=value  # 类的__dict__不支持修改,只能取值,作者做的# setattr(cls,key,value)  # 通过反射setattr(cls, key, Typed(key, value))  # Typed(key, value)调用描述符做类型的判断# 把key和value存到类中return clsreturn decorate@typeassert(name=str, age=int, salary=bool)
class People:def __init__(self, name, age, salary):self.name = nameself.age = ageself.salary = salary@typeassert(name=str, age=int)
class Animal:def __init__(self, name, age):self.name = nameself.age = agea = Animal('xio', 18)
p = People('xio', 18, True)  # decorate(People)()# print(People.__dict__)

自己定制一个property装饰器

class Lazyproperty:def __init__(self, func):self.func = funcdef __get__(self, instance, owner):# self.func是 Room类的area的内存地址,普通函数---需要传对象  area(instance)print('我被执行')return self.func(instance)  # 此时你应该明白,到底是谁在为你做自动传递self的事情class Room:def __init__(self, name, width, length):self.name = nameself.width = widthself.length = length@Lazyproperty  # area=Lazyproperty(area)--->Lazyproperty类的__init__执行,把area放到了Lazyproperty的对象中然后返回了-->area代指Lazyproperty的对象def area(self):return self.width * self.lengthr1 = Room('xxx', 2, 3)
# r1.area是Lazyproperty的对象,类是描述符类---->r1.area会触发描述符类的 __get__方法
print(r1.area)  # 触发描述符类的 __get__ 的执行
print(r1.area)  # 触发描述符类的 __get__ 的执行
print(r1.area)  # 触发描述符类的 __get__ 的执行

自己定制一个classmethod装饰器

class ClassMethod:def __init__(self, func):self.func = funcdef __get__(self, instance, owner):  # 类来调用,instance为None,owner为类本身,实例来调用,instance为实例,owner为类本身,def feedback():print('在这里可以加功能啊...')return self.func(owner)return feedbackclass People:def __init__(self, name):self.name = name@ClassMethod  # get_obj=ClassMethod(get_obj)--->ClassMethod的对象def get_obj(cls):print(cls)print('这是类的绑定方法')# People.get_obj   # 触发 描述符类的__get__,--->返回feedback的内存地址
People.get_obj()  # 其实执行的是feedback()--->self.func--->People类的get_obj方法,self.func(类)--->get_obj(People传入了)

自己定制一个staticmethod装饰器

class StaticMethod:def __init__(self, func):self.func = funcdef __get__(self, instance, owner):def feedback():print('在这里可以加功能啊...')return self.func()return feedbackclass People:def __init__(self, name):self.name = name@StaticMethod  # get_obj=StaticMethod(get_obj)--->StaticMethod的对象def get_obj():print('这是静态方法')# People.get_obj # --->触发__get__执行----feedback内存地址People.get_obj()  # feedback()
  • 带有参数的情况下
Method:def __init__(self, func):self.func = funcdef __get__(self, instance, owner):def feedback(*args, **kwargs):print('在这里可以加功能啊...')return self.func(*args, **kwargs)return feedbackclass People:def __init__(self, name):self.name = name@StaticMethod  # get_obj=StaticMethod(get_obj)--->StaticMethod的对象def get_obj(a, b):print(a, b)print('这是静态方法')# People.get_obj # --->触发__get__执行----feedback内存地址People.get_obj(7, 8)  # feedback()

day32 各种魔法方法相关推荐

  1. 刻意练习:Python基础 -- Task11. 魔法方法

    背景 我们准备利用17天时间,将 "Python基础的刻意练习" 分为如下任务: Task01:变量.运算符与数据类型(1day) Task02:条件与循环(1day) Task0 ...

  2. 技术图文:Python魔法方法之属性访问详解

    背景 今天在B站学习"零基础入门学习 Python"中的第45节"魔法方法:属性访问",这也是我们组织的 Python基础刻意练习活动 的学习任务,其中有这样的 ...

  3. Python中的特殊成员和魔法方法

    1.简介 Python中有大量类似__doc__这种以双下划线开头和结尾的特殊成员及"魔法方法",它们有着非常重要的地位和作用,也是Python语言独具特色的语法之一! __ini ...

  4. python魔法方法和普通方法_Python龙珠训练营九:魔法方法

    魔法方法总是被双下划线包围,例如 __init__ . 魔法方法是面向对象的 Python 的一切,如果你不知道魔法方法,说明你还没能意识到面向对象的 Python 的强大. 魔法方法的"魔 ...

  5. python魔法方法详解

    据说,Python 的对象天生拥有一些神奇的方法,它们总被双下划线所包围,他们是面向对象的 Python 的一切. 他们是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个, ...

  6. python类包含对象的个数_python类与对象各个算数运算魔法方法总结

    1.python类与对象各个算术运算魔法方法总结: 2.各个魔法方法应用举例: 3.实例训练: (1)我们都知道在 Python 中,两个字符串相加会自动拼接字符串,但遗憾的是两个字符串相减却抛出异常 ...

  7. 关于魔法方法的一点总结

    如果按以下方式重写魔法方法 _init_,结果会怎样? class Myclass:def __init__(self):return "I love you" 会报错,因为ini ...

  8. python构造和析构_python魔法方法 构造和析构实例讲解

    目录: 一._ _init_ _(self[, ...]) 二._ _new_ _(cls[, ...]) 三._ _del_ _(self) 四.课时41课后习题及答案 说的那么厉害,那什么是魔法方 ...

  9. python魔法方法好难_一篇干货好文,轻松掌握python魔法方法

    在python学习中,往往你会看到有的名称前面和后面都加上了双下划线,这种写法很特别,到底是什么意思呢? 在python 中由这些名字组成的集合所包含的方法就叫做魔法方法,也叫做特殊方法.今天我们就要 ...

最新文章

  1. 20、C#里面方法的创建和显示
  2. 售价1万7的华为Mate X很贵吗?
  3. sizeof和strlen解析
  4. Hadoop编程调用HDFS
  5. 将函数实现放在头文件中
  6. 剑指OFFER之二进制中1的个数(九度OJ1513)
  7. 1小时搞懂设计模式之工厂模式(简单工厂)
  8. Typescript有什么冷门但是很好用的特性?
  9. JavaScript 函数 对象 数组
  10. 深入理解socket编程的几个函数和两种fd
  11. MVC传参数给js的时候 如果是数值 变量要进行一下转换才能正确识别 例如var aaa = parseInt('@Model.ClickIndex');...
  12. Ural1297 最长回文子串(后缀数组+RMQ)
  13. 《2021中国数据智能产业图谱3.0升级版》重磅发布
  14. 优雅编程之项目开发中的22点编码小建议(三十七)
  15. 概率论 马尔可夫 切比雪夫等定理的解释
  16. Easyui文件上传格式限制
  17. php遇到Allowed memory size of 134217728 bytes exhausted错误解决方法
  18. iOS常用的功能(打电话、发短信、发邮件等)
  19. excel表格的上传和下载
  20. 游戏直播的下一站在哪?战旗TV开启线上线下联动

热门文章

  1. zk集群自动化脚本搭建-只需一个脚本
  2. [分享] (超详细图文)完美解决Mountain Lion10.8.3山狮或10.7.4狮子系统安装windows7 win8多分
  3. 厦门大学计算机学院控制系,厦门大学自动化系简介
  4. Linux中在终端打开图形界面的文件夹的方法
  5. Alibaba之Nacos
  6. TextBox文本框常用属性与事件
  7. Towards Universal Object Detection by Domain Attention翻译
  8. uniapp报错{errMsg: ‘request:fail‘}
  9. 程序员发展:机会远比钱重要
  10. 网名接龙--飞翔我的世界