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)
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())
最后,小编想说:我是一名python开发工程师,整理了一套最新的python系统学习程,想要这些资料的可以关注私信小编“01”即可,希望能对你有所帮助

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值