小猿圈python学习-类的双线下方法

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

调用:不同的双下方法有不同的触发方式,就好比盗墓时触发的机关一样,不知不觉就触发了双下方法,例如:init

以下几个只需大概知道的双下线方法

len方法

class A:

    def __len__(self):

        print(666)

        return 3

a = A()

print(len(a)) # len 一个对象就会触发这个对象的 __len__方法。

class B:

    def __init__(self):

        self.a = 1

        self.b = 2

    def __len__(self):

        return len(self.__dict__)

b = B()

print(len(b))

hash方法

class A:

    def __init__(self):

        self.a = 1

        self.b = 2

    def __hash__(self):

        print("hash method.")

        return hash(str(self.a)+str(self.b))

a = A()

print(hash(a))

eq方法

class A:

    def __init__(self):

        self.a = 1

        self.b = 2

    def __eq__(self,obj):

        print("call eq method.")

        if  self.a == obj.a and self.b == obj.b:

            return True

a = A()

b = A()

print(a == b)

item系列

可以把一个对象变成dict, 可以像dict一样增删改查

class Brand:

    def __init__(self,name):

        self.name=name

    def __getitem__(self, item):

        print("获取KEY",item)

        print(self.__dict__[item])

    def __setitem__(self, key, value):

        print("设置一个key...",key)

        self.__dict__[key]=value

    def __delitem__(self, key):

        print('del obj[key]时,我执行')

        self.__dict__.pop(key)

    def __delattr__(self, item):

        print('del obj.key时,我执行')

        self.__dict__.pop(item)

b=Brand('小猿圈')

b["slogan"] = "自学编程谁不爱小猿圈"

b["website"] = "apeland.cn"

del b["website"]

b['name']='小猿圈Apeland'

b["name"]  # 获取KEY

print(b.__dict__)

需要重点会的双下线方法

str & repr

这2个方法比较像,均可改变对象的字符串显示格式

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)

s1=School('小猿圈','北京','私立')

print('from repr: ',repr(s1))

print('from str: ',str(s1))

print(s1)

'''

str函数或者print函数调用时--->obj.__str__()

repr或者交互式解释器中调用时--->obj.__repr__()

如果__str__没有被定义,那么就会使用__repr__来代替输出

注意:这俩方法的返回值必须是字符串,否则抛出异常

'''

del 析构方法

析构方法,当对象在内存中被释放时,自动触发执行。

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

class Foo:

    def __del__(self):

        print('执行我啦')

f1=Foo()

del f1

print('------->')

#执行输出

执行我啦

------->

new方法

我们知道实例化init会自动执行, 其实在init方法之前,还有一个new方法也会自动执行,你可以在new里执行一些实例化前的定制动作

class Person(object):

    def __init__(self,name):

        self.name = name

        print("--init ....")

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

        """

        cls  : 代表Person这个类本身

        :param args:

        :param kwargs:

        :return:

        """

        print("--in new: ",cls,*args,**kwargs)

        return object.__new__(cls)  # 调用父类的__new__方法,必须这么干 ,要不然__init__方法就不会执行了

p = Person("Alex")

print(p.name)

print(Person)

new方法实现单例模式

单例模式:

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

什么情况下用单例?

对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。如在Windows中就只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态。因此有时确保系统中某个对象的唯一性即一个类只能有一个实例非常重要。

如何保证一个类只有一个实例并且这个实例易于被访问呢?定义一个全局变量可以确保对象随时都可以被访问,但不能防止我们实例化多个对象。一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。这就是单例模式的模式动机。

class Printer(object):

    __instance = None # 用来存唯一的一个实例

    __tasks = []

    def __init__(self,task):

        self.__tasks.append(task)

        print("added a new task in queue..",task)

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

        if cls.__instance is None: # 代表之前还没被实例化过

            obj = object.__new__(cls)

            cls.__instance = obj  # 把第一次实例化的对象 存下来,以后每次实例化都用这个第一次的对象

        return cls.__instance  # 下一次实例化时,就返回第一次实例化的对象

    def jobs(self):

        return self.__tasks

job = Printer("job1 word")

job2 = Printer("job2 png")

job3 = Printer("job3 excel")

print(id(job),id(job2),id(job3)) # 会发现这3个实例的内存id一样

print(job3.jobs())

call方法

对象后面加括号,触发执行。

注:构造方法new的执行是由创建对象触发的,即:对象 = 类名() ;而对于 call 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class Person(object):

    def __init__(self,name):

        self.name = name

        print("--init ....")

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

        """

        cls  : 代表Person这个类本身

        :param args:

        :param kwargs:

        :return:

        """

        print("--in new: ",cls,*args,**kwargs)

        return object.__new__(cls)  # 调用父类的__new__方法,必须这么干 ,要不然__init__方法就不会执行了

    def __call__(self, *args, **kwargs):

        print("-->call",self,*args,**kwargs)

p = Person("Alex")

p()  # 此时会执行__call__

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 参考文献: 《大话设计模式》——吴强 《Python设计模式》——pythontip.com 《23种设计模式》—...
    梁林張斌阅读 2,209评论 0 4
  • 写在前面的话 代码中的# > 表示的是输出结果 输入 使用input()函数 用法 注意input函数输出的均是字...
    FlyingLittlePG阅读 2,682评论 0 8
  • Python语言特性 1 Python的函数参数传递 看两个如下例子,分析运行结果: 代码一: a = 1 def...
    伊森H阅读 2,971评论 0 15
  • property、魔法属性和魔法方法、多重继承和多继承 1.5 property 学习目标 1. 能够说出什么要...
    Cestine阅读 762评论 0 1
  • Python语言特性 1 Python的函数参数传递 看两个如下例子,分析运行结果: 代码一: a = 1 def...
    时光清浅03阅读 443评论 0 0