python面向对象基础(三)内置方法 __xx__
__str__和__repr__,__format__
改变对象的字符串显示__str__,__repr__
自定制格式化字符串__format__
#_*_coding:utf-8_*_
format_dict={
'格式1':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
'格式2':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
'格式3':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
}
class School:
def __init__(self,name,addr,type):
self.name=name
self.addr=addr
self.type=type
def __repr__(self):
return 'School(%s,%s)' %(self.name,self.addr)
def __str__(self):
return '(%s,%s)' %(self.name,self.addr)
def __format__(self, format_spec):
# if format_spec
if not format_spec or format_spec not in format_dict:
format_spec='格式1'
fmt=format_dict[format_spec]
return fmt.format(obj=self)
s1=School('清华','北京','公立')
print('from repr: ',repr(s1))
print('from str: ',str(s1))
print(s1)
'''
str函数或者print函数--->obj.__str__()
repr或者交互式解释器--->obj.__repr__()
如果__str__没有被定义,那么就会使用__repr__来代替输出
'''
'''
注意:这三个方法的返回值必须是字符串,否则抛出异常
'''
print(format(s1,'格式1'))
print(format(s1,'格式2'))
print(format(s1,'格式3'))
print(format(s1,'xxx'))

class B:
def __str__(self):
return 'str : class B'
def __repr__(self):
return 'repr : class B'
b=B()
print('%s'%b)
print('%r'%b)

__del__
析构方:当对象在内存中被释放的同时自动触发执行该方法。
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
class Foo:
def __del__(self):
print('执行我啦')
f1=Foo()
del f1
# 执行我啦
print('------->')
f1
# NameError: name 'f1' is not defined
item系列
__getitem__\__setitem__\__delitem__
==》__dict__
在Python中,如果我们想实现创建类似于序列和映射的类,可以通过重写魔法方法__getitem__、__setitem__、__delitem__方法去模拟。
这些魔术方法的原理就是:当我们对类的属性item进行下标的操作时,首先会被__getitem__()、__setitem__()、__delitem__()拦截,从而进行我们在方法中设定的操作,如赋值,修改内容,删除内容等等。
对类的属性item进行下标的操作==>obj["属性"]
class A:
def __init__(self,name):
self.name=name def __getitem__(self, item):
print("呵呵你看不到") def __setitem__(self, key, value):
self.__dict__[key]=value
print('设置了 obj 属性 [%s] 为 %s'%(key,value)) def __delitem__(self, key):
print('del obj[%s]时,我执行'%key)
self.__dict__.pop(key) def __delattr__(self, item):
print('del obj.%s时,我执行'%item)
self.__dict__.pop(item) def __setattr__(self, item,value):
print("调用了__setattr__方法")
self.__dict__[item]=value def daren(self):
pass a=A('斌哥')
#这个过程也调用了__setattr__方法 print(a.__dict__)
# {'name': '斌哥'} a.name
#==>'斌哥' print(a['name'])
#调用了__getitem__方法
# 呵呵你看不到
# None a['age']=18
#=触发=__setitem__>设置了 obj 属性 [age] 为 18
a.age=19
#=触发=__setitem__>调用了__setattr__方法
a['appear']='很帅'
# #=触发=>设置了 obj 属性 [appear] 为 很帅 del a.appear
#触发__delattr__==>del obj.appear时,我执行
del a['age']
#触发__delitem__==>del obj[age]时,我执行
a.school='nc'
print(a.__dict__)
# {'school': 'nc', 'name': '斌哥'}
# 结论:感觉属性维护了一个doc字典 # 结论 : obj.属性 调用 使用的是xxattr()方法
#xxitem()方法提供了 访问属性一个【】接口
__dict__
发现dict是一个mappingproxy类型,为何不是一个简单的python dict呢?
>>> class A(object): pass
...
>>> A.__dict__
mappingproxy({'__module__': '__main__', '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None})
不清楚,回头研究下。
Python的实例有自己的__dict__,它对应的类也有自己的__dict__ (但是有些特殊的对象是没有__dict__属性的)
class A:
def __init__(self,name):
self.name=name
def __len__(self):
return len(self)
a=A('斌哥')
print(A.__dict__)
# {'__doc__': None, '__module__': '__main__', '__len__': <function A.__len__ at 0x0000014FF1C71EA0>,
# '__init__': <function A.__init__ at 0x0000014FF1BE1730>, '__weakref__': <attribute '__weakref__' of 'A' objects>,
# '__dict__': <attribute '__dict__' of 'A' objects>} print(a.__dict__)
# {'name': '斌哥'} class B(A):
def __init__(self,age,name):
super().__init__(name)
self.age=age
def __len__(self):
return len(self)
b=B(18,"bb")
print(B.__dict__)
print(b.__dict__) # {'__doc__': None, '__module__': '__main__',
# '__init__': <function B.__init__ at 0x0000014FF1CB1A60>,
# '__len__': <function B.__len__ at 0x0000014FF1CB1730>}
#
# {'name': 'bb', 'age': 18}
class A:
a = 0
b = 1 def __init__(self):
self.a = 2
self.b = 3 def test(self):
print('a normal func.') @staticmethod
def static_test(a):
print('a static func.'+a) @classmethod
def class_test(cls):
print('a calss func.') obj = A()
print(A.__dict__)
print(obj.__dict__)
A.static_test("")
A.class_test()


1.类的静态函数、类函数、普通函数、全局变量以及一些内置的属性都是放在类__dict__里的
2.对象的属性(不含类的)保存在实例__dict___里
3.子类有自己的__dict__, 父类也有自己的__dict__,子类的全局变量和函数放在子类的dict中,父类的放在父类dict中。对象也这样。
4.内置的数据类型没有__dict__属性
__dir__
dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。如果参数包含方法__dir__(),该方法将被调用。如果参数不包含__dir__(),该方法将最大限度地收集参数信息。
dir([object])
参数说明:
- object -- 对象、变量、类型。
class A(object): pass
a=A()
a.name="wqbin" print(A.__dict__)
print(a.__dict__)
print(a.__dir__())


Note:dir是最大范围的收集一个类或者一个对象的属性,所以是包含__dict__.keys
__call__
对象后面加括号,触发执行。
对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
class C:
def __init__(self):
print("__init__")
def __call__(self, *args, **kwargs):
print('__call__')
obj = C() # 执行 __init__
obj() # 执行 __call__
为什么函数对象可以触发?
f = abs print(dir(f))

__len__
果一个类表现得像一个list,要获取有多少个元素,就得用 len() 函数。
要让 len() 函数工作正常,类必须提供一个特殊方法__len__(),它返回元素的个数。
class A:
def __init__(self):
self.a = 1
self.b = 2 def __len__(self):
return len(self.__dict__)
a = A()
print(len(a))
#2
__hash__
class A:
def __init__(self):
self.a = 1
self.b = 2 def __hash__(self):
return hash(str(self.a)+str(self.b))
a = A()
print(hash(a))
class A:
def __init__(self):
self.a = 1
self.b = 2 def __hash__(self):
# return str(self.a)+'哈哈'+str(self.b) return int(str(1024)+str(self.a)+str(self.b))
a = A()
print(hash(a))
# TypeError: __hash__ method should return an integer
__eq__
__eq__ 当判断两个对象的是否相等时,==触发此方法
class A:
def __init__(self):
self.a = 1
self.b = 2 def __eq__(self,obj):
if self.a == obj.a and self.b == obj.b:
return True
a = A()
b = A()
print(a == b) #true
== 比较的是两个对象的内容是否相等,即内存地址可以不一样,内容一样就可以了。这里比较的并非是同一片叶子,可能叶子的种类或者脉络相同就可以了。默认会调用对象的 __eq__()方法。
python面向对象基础(三)内置方法 __xx__的更多相关文章
- Python面向对象编程及内置方法
在程序开发中,要设计一个类,通常需要满足以下三个要求: [1]类名 这类事物的名字,满足大驼峰命名法 [2]属性 这类事物具有什么样的特征 [3]方法 这类事物具有什么样的行为 定义简单的类: 定义只 ...
- python面向对象 : 反射和内置方法
一. 反射 1. isinstance()和issubclass() isinstance( 对象名, 类名) : 判断对象所属关系,包括父类 (注:type(对象名) is 类名 : 判断对象所属 ...
- python 面向对象反射以及内置方法
一.反射 什么是反射:可以用字符串的方式去访问对象的属性,调用对象的方法(但是不能去访问方法),python中一切皆对象,都可以使用放射. 反射的四种方法: hasattr:hasattr(objec ...
- python 面向对象 类的内置方法
判断是不是类cls的对象 class A: pass a = A() print(isinstance(a,A)) 判断类sub是不是super的子类 class A: pass class B(A) ...
- python面向对象--类的内置方法
#isinstance(obj,cls)判断obj是否是类cls的实例 #issubclass(cls,cls1)判断cls是否是cls1的子类或派生类 class Foo: pass class B ...
- Python 数据类型常用的内置方法(三)
目录 Python 数据类型常用的内置方法(三) 1.列表内置方法 1.sort():升序 2.reverse():颠倒顺序 3.列表比较运算 2.字典内置方法 1.对Key的操作 2.len( )- ...
- 铁乐学python_day24_面向对象进阶1_内置方法
铁乐学python_day24_面向对象进阶1_内置方法 题外话1: 学习方法[wwwh] what where why how 是什么,用在哪里,为什么,怎么用 学习到一个新知识点的时候,多问问上面 ...
- Python 数据类型常用的内置方法(一)
目录 Python 数据类型常用的内置方法 1.整型 int 2.浮点型 float 字符串转浮点型: 3.字符串 str 多种类型转字符型: 索引 切片 len( )方法:统计字符串长度/个数 移除 ...
- Python 数据类型常用的内置方法(二)
目录 Python 数据类型常用的内置方法(二) 1.字符串类型常用内置方法 1.upper.lower.isupper.islower 2.startswith.endswith 3.format ...
- Python之路(第二十九篇) 面向对象进阶:内置方法补充、异常处理
一.__new__方法 __init__()是初始化方法,__new__()方法是构造方法,创建一个新的对象 实例化对象的时候,调用__init__()初始化之前,先调用了__new__()方法 __ ...
随机推荐
- C# PC版微信消息监听自动回复
最近有个微商客户需要搞个 个人微信监听群消息关键字并实现自动回复功能, 因为他有很多群 很多买家咨询的话 一个个回复太麻烦, 客户要求 比如群里有人发 关键字 产品1 则自动回复产品1的相关描述 ...
- Linux多线程编程 - sleep 和 pthread_cond_timedwait
#include <stdio.h> #include <stdlib.h> int flag = 1; void * thr_fn(void * arg) { while ...
- spring事务使用
spring的事务管理有几种方式实现,如何实现? 事务的实现方式:实现方式共有两种:编码方式:声明式事务管理方式 基于AOP技术实现的声明式事务管理,实质就是:在方法执行前后进行拦截,然后再目标方法开 ...
- pyton 类(4) 静态方法
class Cat(): tag = ' 猫科动物 ' def __init__(self, name): self.name = name @staticmethod def breah(): pr ...
- 使用Iview时候 报:no-parsing-error Parsing error: x-invalid-end-tag 解决办法
解决办法有两种解决办法: 1.MenuItem修改为:menu-item 2.在根目录下 .eslintrc.js 文件 rules 下添加: "vue/no-parsing-error&q ...
- 最全最新java面试题系列全家桶(带答案)
最全最新java面试题系列全家桶(带答案) 置顶 2019年04月06日 22:40:28 青春季风暴 阅读数 14082 文章标签: java面试题技术栈 更多 分类专栏: 面试 版权声明:本文 ...
- docker-compose.yml 部署Nginx、Java项目、MySQL、Redis
version: "3.7" services: nginx: image: nginx restart: always container_name: nginx environ ...
- [C#.net]使用Thread.Sleep界面卡死的问题解决方法
很多初学者在写C#程序的时候,需要程序等待某个时间,但是又不想用比较繁琐的线程等操作,因此用Thread.Sleep()函数,但是这个函数在等待过程中会操作界面的卡死,那么,如何能保证既不卡死又能达到 ...
- .net get set用法
在早期学习c#的过程中,经常遇到这样的语句: public string StudentName{ get{return stuName;} set{stuNa ...
- [转载]flex中的正则表达式
原文:https://blog.csdn.net/hczhiyue/article/details/20483209 (1)单字符匹配* ‘x’ 匹配字符 x.* ‘.’ 匹配任意一个字符(字节),除 ...