day32 各种魔法方法
各种魔法方法
- `__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 各种魔法方法相关推荐
- 刻意练习:Python基础 -- Task11. 魔法方法
背景 我们准备利用17天时间,将 "Python基础的刻意练习" 分为如下任务: Task01:变量.运算符与数据类型(1day) Task02:条件与循环(1day) Task0 ...
- 技术图文:Python魔法方法之属性访问详解
背景 今天在B站学习"零基础入门学习 Python"中的第45节"魔法方法:属性访问",这也是我们组织的 Python基础刻意练习活动 的学习任务,其中有这样的 ...
- Python中的特殊成员和魔法方法
1.简介 Python中有大量类似__doc__这种以双下划线开头和结尾的特殊成员及"魔法方法",它们有着非常重要的地位和作用,也是Python语言独具特色的语法之一! __ini ...
- python魔法方法和普通方法_Python龙珠训练营九:魔法方法
魔法方法总是被双下划线包围,例如 __init__ . 魔法方法是面向对象的 Python 的一切,如果你不知道魔法方法,说明你还没能意识到面向对象的 Python 的强大. 魔法方法的"魔 ...
- python魔法方法详解
据说,Python 的对象天生拥有一些神奇的方法,它们总被双下划线所包围,他们是面向对象的 Python 的一切. 他们是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个, ...
- python类包含对象的个数_python类与对象各个算数运算魔法方法总结
1.python类与对象各个算术运算魔法方法总结: 2.各个魔法方法应用举例: 3.实例训练: (1)我们都知道在 Python 中,两个字符串相加会自动拼接字符串,但遗憾的是两个字符串相减却抛出异常 ...
- 关于魔法方法的一点总结
如果按以下方式重写魔法方法 _init_,结果会怎样? class Myclass:def __init__(self):return "I love you" 会报错,因为ini ...
- python构造和析构_python魔法方法 构造和析构实例讲解
目录: 一._ _init_ _(self[, ...]) 二._ _new_ _(cls[, ...]) 三._ _del_ _(self) 四.课时41课后习题及答案 说的那么厉害,那什么是魔法方 ...
- python魔法方法好难_一篇干货好文,轻松掌握python魔法方法
在python学习中,往往你会看到有的名称前面和后面都加上了双下划线,这种写法很特别,到底是什么意思呢? 在python 中由这些名字组成的集合所包含的方法就叫做魔法方法,也叫做特殊方法.今天我们就要 ...
最新文章
- 20、C#里面方法的创建和显示
- 售价1万7的华为Mate X很贵吗?
- sizeof和strlen解析
- Hadoop编程调用HDFS
- 将函数实现放在头文件中
- 剑指OFFER之二进制中1的个数(九度OJ1513)
- 1小时搞懂设计模式之工厂模式(简单工厂)
- Typescript有什么冷门但是很好用的特性?
- JavaScript 函数 对象 数组
- 深入理解socket编程的几个函数和两种fd
- MVC传参数给js的时候 如果是数值 变量要进行一下转换才能正确识别 例如var aaa = parseInt('@Model.ClickIndex');...
- Ural1297 最长回文子串(后缀数组+RMQ)
- 《2021中国数据智能产业图谱3.0升级版》重磅发布
- 优雅编程之项目开发中的22点编码小建议(三十七)
- 概率论 马尔可夫 切比雪夫等定理的解释
- Easyui文件上传格式限制
- php遇到Allowed memory size of 134217728 bytes exhausted错误解决方法
- iOS常用的功能(打电话、发短信、发邮件等)
- excel表格的上传和下载
- 游戏直播的下一站在哪?战旗TV开启线上线下联动
热门文章
- zk集群自动化脚本搭建-只需一个脚本
- [分享] (超详细图文)完美解决Mountain Lion10.8.3山狮或10.7.4狮子系统安装windows7 win8多分
- 厦门大学计算机学院控制系,厦门大学自动化系简介
- Linux中在终端打开图形界面的文件夹的方法
- Alibaba之Nacos
- TextBox文本框常用属性与事件
- Towards Universal Object Detection by Domain Attention翻译
- uniapp报错{errMsg: ‘request:fail‘}
- 程序员发展:机会远比钱重要
- 网名接龙--飞翔我的世界