__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__的更多相关文章

  1. Python面向对象编程及内置方法

    在程序开发中,要设计一个类,通常需要满足以下三个要求: [1]类名 这类事物的名字,满足大驼峰命名法 [2]属性 这类事物具有什么样的特征 [3]方法 这类事物具有什么样的行为 定义简单的类: 定义只 ...

  2. python面向对象 : 反射和内置方法

    一. 反射 1. isinstance()和issubclass() isinstance( 对象名, 类名) : 判断对象所属关系,包括父类  (注:type(对象名) is 类名 : 判断对象所属 ...

  3. python 面向对象反射以及内置方法

    一.反射 什么是反射:可以用字符串的方式去访问对象的属性,调用对象的方法(但是不能去访问方法),python中一切皆对象,都可以使用放射. 反射的四种方法: hasattr:hasattr(objec ...

  4. python 面向对象 类的内置方法

    判断是不是类cls的对象 class A: pass a = A() print(isinstance(a,A)) 判断类sub是不是super的子类 class A: pass class B(A) ...

  5. python面向对象--类的内置方法

    #isinstance(obj,cls)判断obj是否是类cls的实例 #issubclass(cls,cls1)判断cls是否是cls1的子类或派生类 class Foo: pass class B ...

  6. Python 数据类型常用的内置方法(三)

    目录 Python 数据类型常用的内置方法(三) 1.列表内置方法 1.sort():升序 2.reverse():颠倒顺序 3.列表比较运算 2.字典内置方法 1.对Key的操作 2.len( )- ...

  7. 铁乐学python_day24_面向对象进阶1_内置方法

    铁乐学python_day24_面向对象进阶1_内置方法 题外话1: 学习方法[wwwh] what where why how 是什么,用在哪里,为什么,怎么用 学习到一个新知识点的时候,多问问上面 ...

  8. Python 数据类型常用的内置方法(一)

    目录 Python 数据类型常用的内置方法 1.整型 int 2.浮点型 float 字符串转浮点型: 3.字符串 str 多种类型转字符型: 索引 切片 len( )方法:统计字符串长度/个数 移除 ...

  9. Python 数据类型常用的内置方法(二)

    目录 Python 数据类型常用的内置方法(二) 1.字符串类型常用内置方法 1.upper.lower.isupper.islower 2.startswith.endswith 3.format ...

  10. Python之路(第二十九篇) 面向对象进阶:内置方法补充、异常处理

    一.__new__方法 __init__()是初始化方法,__new__()方法是构造方法,创建一个新的对象 实例化对象的时候,调用__init__()初始化之前,先调用了__new__()方法 __ ...

随机推荐

  1. C# PC版微信消息监听自动回复

    最近有个微商客户需要搞个 个人微信监听群消息关键字并实现自动回复功能, 因为他有很多群  很多买家咨询的话 一个个回复太麻烦, 客户要求 比如群里有人发 关键字 产品1  则自动回复产品1的相关描述 ...

  2. Linux多线程编程 - sleep 和 pthread_cond_timedwait

    #include <stdio.h> #include <stdlib.h> int flag = 1; void * thr_fn(void * arg) {   while ...

  3. spring事务使用

    spring的事务管理有几种方式实现,如何实现? 事务的实现方式:实现方式共有两种:编码方式:声明式事务管理方式 基于AOP技术实现的声明式事务管理,实质就是:在方法执行前后进行拦截,然后再目标方法开 ...

  4. pyton 类(4) 静态方法

    class Cat(): tag = ' 猫科动物 ' def __init__(self, name): self.name = name @staticmethod def breah(): pr ...

  5. 使用Iview时候 报:no-parsing-error Parsing error: x-invalid-end-tag 解决办法

    解决办法有两种解决办法: 1.MenuItem修改为:menu-item 2.在根目录下 .eslintrc.js 文件 rules 下添加: "vue/no-parsing-error&q ...

  6. 最全最新java面试题系列全家桶(带答案)

    最全最新java面试题系列全家桶(带答案) 置顶 2019年04月06日 22:40:28 青春季风暴 阅读数 14082 文章标签: java面试题技术栈 更多 分类专栏: 面试   版权声明:本文 ...

  7. docker-compose.yml 部署Nginx、Java项目、MySQL、Redis

    version: "3.7" services: nginx: image: nginx restart: always container_name: nginx environ ...

  8. [C#.net]使用Thread.Sleep界面卡死的问题解决方法

    很多初学者在写C#程序的时候,需要程序等待某个时间,但是又不想用比较繁琐的线程等操作,因此用Thread.Sleep()函数,但是这个函数在等待过程中会操作界面的卡死,那么,如何能保证既不卡死又能达到 ...

  9. .net get set用法

    在早期学习c#的过程中,经常遇到这样的语句: public string StudentName{           get{return stuName;}           set{stuNa ...

  10. [转载]flex中的正则表达式

    原文:https://blog.csdn.net/hczhiyue/article/details/20483209 (1)单字符匹配* ‘x’ 匹配字符 x.* ‘.’ 匹配任意一个字符(字节),除 ...