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__()方法 __ ...
随机推荐
- PYTHON 100days学习笔记007-2:python数据类型补充(2)
目录 day007:python数据类型补充(2) 1.Python3 元组 1.1 访问元组 1.2 删除元组 1.3 元组运算符 1.4 元组索引,截取 1.5 元组内置函数 2.python3 ...
- linux:date 计算一组命令所花费的执行时间
date 命令可以用于计算一组命令所花费的执行时间 可以以不同的格式来读取.设置日期. (1) 读取日期: $ date Thu May 20 23:09:04 IST 2010 (2) 打印纪元时: ...
- Hadoop部署(伪分布式系统)
hadoop安装 #修改主机名 hostnamectl set-hostname hadoop #修改hosts vim /etc/hosts #追加到末尾 10.0.0.11 hadoop 安装必备 ...
- mongodb 批量替换内容的语句
// 注意上面的集合要和下面的集合名称相同 db.rand_web_test.find( { 'content': /^.*要替换的字符串.*$/ } ).forEach( function (ite ...
- URI解析
这里主要参考 RFC3986 文档. URI可以分为URL,URN或同时具备locators 和names特性的一个东西.URN作用就好像一个人的名字,URL就像一个人的地址.换句话说:URN确定了东 ...
- T100——作业action执行其他P作业,后台背景执行完后才能继续操作改作业
范例:如axmt500订单,查询开单占用量: 客制作业cxmp500,通过参数-订单号,查询该订单下的料件,目前有库存量.开单占用量.库存可用量,查询后更新到该订单下的单身对应栏位: 现在axmt50 ...
- docker-Overlay原生网络
节点1/键值存储:192.168.50.130 :192.168.50.131 1.下载Consul二进制包并启动 wget https://releases.hashicorp.com/consul ...
- C# WPF集中引用图片等资源的路劲方式
第一内部资源: pack://application:,,,/images/my.jpg 第二 外部程序资源: pack://SiteOfOrigin:,,,/images/my.jpg 需要将资源放 ...
- git的详细安装
git的详细安装 Git 是时候动手尝试下 Git 了,不过得先安装好它.有许多种安装方式,主要分为两种,一种是通过编译源代码来安装:另一种是使用为特定平台预编译好的安装包. 从源代码安装 若是条件允 ...
- luogu题解 P3709 【大爷的字符串题】
题目链接: https://www.luogu.org/problemnew/show/P3709 思路: 首先我是没读懂题目的,浏览了讨论区的dalao发现才知道就是求区间众数的出现次数. 然后肯定 ...