Python基础: 双下方法(python基础面试题及答案)

网友投稿 678 2022-09-21

Python基础: 双下方法(python基础面试题及答案)

Python基础: 双下方法(python基础面试题及答案)

1、双下方法

定义:双下方法是特殊方法,它是解释器提供的 由双下划线加方法名加双下划线 方法名的具有特殊意义的方法,双下方法主要是python源码程序员使用的,我们在开发中尽量不要使用双下方法,但是深入研究双下方法,更有益于我们阅读源码。

(1)调用:不同的双下方法有不同的触发方式,

<1> __ len__ -- len() 触发

class A(object):

def __init__(self,name):

self.name = name

print("触发了__init__")

def __len__(self): # len() 触发

print("走这里")

return len(self.name) # return len("xqrqwr") str中__len__

# 必须有返回值,返回值的类型必须是整型

a = A("xqrqwr")

print(len(a))

# str

a = "12345" # str这个类的实例

lst = [1,2,3,4,4,5,5,5,5] # list这个类的实例

print(len(a))

print(len(lst))

<2> __ hash__ --hash() 触发

class A(object):

def __init__(self,name,age):

self.name = name

self.age = age

def __hash__(self): # hash()

hash({1,2,345}) # 可变数据类,不可数据类型

return 1

# 必须有返回值,返回值的类型必须是整型

a = A("meet",25)

print(hash(a))

<3> __ str__ --print 或者 str() 触发

class A:

def __init__(self,name,age,sex):

self.name = name

self.age = age

self.sex = sex

def __str__(self): # print 触发 str()

print(111)

return f"姓名:{self.name} 年龄:{self.age} 性别:{self.sex}"

# 必须有返回值,返回值的类型必须是字符串

a = A("mee",20,"男")

a1 = A("mee1",200,"男1")

str(a)

print(a)

print(a1)

# 以下对比:

a = A("mee",20,"男")

a1 = A("mee2",200,"女")

print(f"姓名:{a.name} 年龄:{a.age} 性别:{a.sex}") # "姓名:meet 年龄:20 性别:男"

print(f"姓名:{a1.name} 年龄:{a1.age} 性别:{a1.sex}") # "姓名:meet2 年龄:200 性别:女"

<4> __ repr__ --print 或者 %r 触发

class A:

def __init__(self):

pass

def __repr__(self): # print触发 %r

print(1111)

return "天魔"

def __str__(self): # str 优先级高于 repr 两个都存在就只执行str

return "小元"

a = A()

print("%r"%(a))

<5> __ call__ --对象调用时触发,对象后加括号即:对象() 或者 类()()

class A:

def __init__(self):

pass

def __call__(self, *args, **kwargs): # 对象()时调用的__call__

print("走我")

print(*args, **kwargs)

a = A()

a()

<6> __ eq__ 等于

class A(object):

def __init__(self,name,age):

self.name = name

self.age = age

def __eq__(self, other): # a == a1

if self.name == other.name:

return True

else:

return False

a = A("mee",56)

a1 = A("mee",108)

print(a == a1)

<7> __ del__ 构造方法,当对象在内存中被释放时,自动触发执行

​ 此方法一般情况下无需定义,因为python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为内存的分配和释放都是交给python解释器类执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

class A:

def __init__(self):

pass

def __del__(self): del 触发

print("删除时执行我")

a = A()

import time

time.sleep(5)

del a

a = 1

b = a

a = b

垃圾回收机制:

# 80 5/s

# 引用计数

# 标记清除

# 分袋回收 袋一:10 2/h 袋二: 5/3 4h 袋三: 3 20h

<8> __ item__ 系列 可以像操作字典一样操作实例方法

dic["键"] = 值

del dic["键"]

dic["键"]

class A:

def __init__(self,name,age):

self.name = name

self.age = age

def __getitem__(self, item):

print(self.__dict__)

print(self.__dict__[item]) # self.__dict__ 获取的就是字典

def __setitem__(self, key, value):

self.__dict__[key] = value

def __delitem__(self, key):

del self.__dict__[key]

a = A("meet",58)

a["sex"] = "男"

a["sex"]

del a["sex"]

print(a.__dict__)

<9> __ new__ 单例模式(工厂模式)

​ 单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

class A(object):

def __init__(self,name): # 初始化

self.name = name

print("我是__init__,先走我")

def __new__(cls, *args, **kwargs):

print("我是__new__,先走我")

return "啦啦啦"

a = A("meet")

print("我是谁:",a)

'''

遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333

寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!

'''

class A(object):

def __init__(self,name): # 初始化

self.name = name

print("我是__init__,先走我")

def __new__(cls, *args, **kwargs):

obj = object.__new__(A)

print("我在哪:",obj)

return obj # obj == __init__()

a = A("meet")

print("我是谁:",a)

class A(object):

def __init__(self,name): # 初识化

self.name = name

def __new__(cls, *args, **kwargs):

obj = object.__new__(A) # 调用的是object类中的__new__ ,只有object类中的__new__能够创建空间

return obj #本质: obj == __init__() return __init__() # 触发了__init__方法

a = A("mee") # a是对象的内存地址

a1 = A("天魔") # a是对象的内存地址

a2 = A("天阳") # a是对象的内存地址

print(a.name)

print(a1.name)

print(a2.name)

# 先执行__new__方法再执行__init__方法

class A:

__a = None #__a = 0x000001F346079FD0

def __init__(self,name,age):

self.name = name

self.age = age

def __new__(cls, *args, **kwargs):

if cls.__a is None:

obj = object.__new__(cls)

cls.__a = obj

return cls.__a

a = A("mee",123) # 地址0x000001F346079FD0

a1 = A("天魔",11)

print(a.name)

print(a1.name)

单例模式:不管创建多少次,使用的都是同一个内存空间

模块的导入,手写的单例模式

实例化对象时发生的事:

创建对象,并开辟对象空间 __ next__

自动执行 __ init方法,隐性的将对象地址传给self

将对象属性封装到对象空间

2、上下文

(1)__ enter__

(2)__ exit__

class my_open:

def __init__(self,file,mode="r",encoding="utf-8"):

self.file = file

self.mode = mode

self.encoding = encoding

def __enter__(self):

self.f = open(self.file,self.mode,encoding=self.encoding)

return self.f

def __exit__(self, exc_type, exc_val, exc_tb):

print(exc_type,exc_val,exc_tb) # 没有错误时就是None

self.f.close()

with my_open("a.txt") as ffff:

for i in ffff:

print(i)

print(ffff.read(1111))

print(ffff.read())

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:关于Unix中grep的alias设置的一点建议
下一篇:Unix stty的快捷键
相关文章

 发表评论

暂时没有评论,来抢沙发吧~