zoukankan      html  css  js  c++  java
  • day 24 内置函数(补充)

    一。 内置函数 
    1.__len__ 与 len()


    # class A:
    # def __init__(self,name,age,sex,cls):
    # self.name = name
    # self.age = age
    # self.sex = sex
    # self.cls = cls
    # def __len__(self):
    # return len(self.__dict__)
    #
    # # 有一个内置函数 和内置方法len()是唯一对应的关系
    # a1 = A('alex',81,'不详',2)
    # a1.hobby = '烫头'
    # a2 = A('egon',20,'不详',3)
    # a3 = A('yuan',21,'不详',4)
    # print(len(a1))
    # print(len(a2))
    # print(len(a3))



    2.
    字典的存储
    # hash

    class A:
    def __init__(self,name,age,sex,cls):
    self.name = name
    self.age = age
    self.sex = sex
    self.cls = cls
    def __hash__(self):
    return 0
    a1 = A('alex',81,'不详',2)
    print(hash(a1))
    每一次的哈希值都不同,为什么可以直接哈希,因为object类里有__hash__方法
     

    二。__str__ 与 __repr__  与  print()

    ps: 总结:

      1.print() 想文件中写,print() 替你将数据类型转化成字符串打印出来

      2.__str__ :  object 类中的__str__ 就是返回一个数据类型的内存地址

    l = [1,2,3,4]
    print(l)   # 向文件中写   print替你将数据类型转化成字符串打印出来
    
    class List:
        def __init__(self,*args): 5
            self.l = list(args)
        def __str__(self):
            return '[%s]'%(','.join([str(i) for i in self.l]))
    l = List(1,2,3,4,5)
    print(l)   #--> l.__str__()   # object类中的__str__就是返回一个数据的内存地址
    print(l)
    print(str(l))
    print('%s'%l)
    print(obj)   的结果 是 obj.__str__()的结果
    str(obj)   的结果 也是 obj.__str__()的结果
    '%s'%obj   的结果 也是 obj.__str__()的结果
    class Teacher:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        # def __str__(self):
        #     return "Teacher's object is %s" %self.name
        def __repr__(self):
            return "repr %s" %self.name
    a = Teacher('alex',18)
    b = Teacher('wusir',18)
    
    print(a)
    print(repr(b))
    # repr(obj)的结果和obj.__repr__()是一样的
    # '%r'%(obj)的结果和obj.__repr__()是一样的

    总结:

      1.实际上上述三种结果都是__str__的返回值

      2.当然:如果我们不手动改写object中 的上下划线str或者repr,就会默认调用object类中的方法,默认返回的是 内存地址

    思考:why? repr(1)  与 repr('1'):的打印结果不同?

    因为:在整形中 定义的repr方法,与在str中定义的repr方法定义的函数方法的返回值不同。  即在class int 与 class str 中的 __repr__ 方法的返回值不同

    class Teacher:
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __str__(self):
            return "Teacher's object %s"%self.name
        def __repr__(self):
            return 'repr function %s'%self.name
    a = Teacher('alex',80)
    b = Teacher('egon',80)
    print(a)
    print(b)

    PS:总结:

      1.到需要使用__str__的方法时,找不到__str__方法时,就会找__repr__方法。

      2.当需要使用__repr__的方法时,找不到__repr__的方法时,就会找父类的或object的__repr__方法,这是默认返回的时内存地址

      3.repr()方法是 str()方法的备胎。嘿嘿嘿(偷笑)

      3.实际上:len()和 repr() 方法的返回值都是依赖__len__和__repr__方法来返回值的

    三。__len__方法 与 __hash__方法

    # class A:
    # def __init__(self):pass
    # def __len__(self):pass
    # def len(obj):
    # obj.__len__()
    # a = A()
    # a.__len__()
    # len() # 为什么要归一化设计呢?
    # 更接近面向函数编程,简单且节省代码

    # len()  obj.__len__()  返回值是一致的
    # len() 的结果是依赖 obj.__len__()
    # hash() 的结果是依赖 obj.__hash__()

    # str() 的结果是依赖 obj.__str__()
    # print(obj) 的结果是依赖 obj.__str__()
    # %s 的结果是依赖 obj.__str__() # 语法糖
    #
    # repr() 的结果是依赖 obj.__repr__()
    # %r 的结果是依赖 obj.__repr__()
    # repr是str的备胎
    思考:如果str与repr 我只能实现一个,那选哪个?# __str__
    # __repr__   一定是选择repr


    什么是语法糖?语法糖的定义?
      
      答:语法糖就是可以让数据结构变得更加简单,就像吃了糖一样甜。这就是语法糖。

    四。__format__方法?
      
    class Format:
        def __init__(self,name,age,hobby):
            self.name = name
            self.age = age
            self.hobby = hobby
    
        def __format__(self,format_spec):
            return format_spec.format(obj = self)
    
    person = Format('alex',18,'')
    format_spec = '{obj.name}-{obj.age}-{obj.hobby}'
    print(format(person,format_spec))

     

    五:__call__?

    class Teacher:
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __call__(self):
            print(123)
    
    
    t = Teacher('wusir',18)
    t()

    靠?方法加(),什么鬼?  

    对象名()   相当于调用了类内置的__call__方法

    print(callable(类名)):是否可调用的

    如果一个对象是否可调用,取决于这个对象对应的类是否有__call__方法


    2.__eq__?
    class A:pass
    a = A()
    b = A()
    print(a == b)

    返回False
    因为连个对象的内存地址是不一样的,
    # class A:
    #     def __eq__(self, other):
    #         # if self.__dict__ == other.__dict__:
    #             return True
    # # __eq__()
    # a = A()
    # a.name = 'alex'
    # b = A()
    # b.name = 'egon'
    # print(a)
    # print(b)
    # print(a == b)
    
    # == 是由__eq__的返回值来决定的

    # == 是由__eq__的返回值来决定的

    3.__del__ 析构方法?

    在删除一个对象的时候做一些收尾工作。

    class A:
        def __init__(self):
            self.f = open('文件','w')
    
    a = A()
    print('aaa')

    把a对象删除不用了

    这是文件并没有关闭,文件没有关闭会占内存。

    应该在删除对象是进行一个析构方法,用操作系统将文件关闭在删除文件

    class A:
        def __init__(self):
            pass
            self.f = open('文件','w')
        def __del__(self):
            self.f.close()
            print('执行我了')
    
    a = A()
    del a
    print(a)
    print('aaa')

    4.__new__?

    __new__  构造方法

    实例化对象的时候

    创建对象的过程

    init  初始化

       设计模式 —— 单例模式

     单例模式 就是 一个类 只能有一个实例
    # class A:pass
    # a = A()
    # b = A()
    # print(a)
    # print(b)
    
    # class B:
    #     __instance = None
    #     def __new__(cls, *args, **kwargs):
    #         if cls.__instance is None:
    #             obj = object.__new__(cls)
    #             cls.__instance = obj
    #         return cls.__instance
    #     def __init__(self,name,age):
    #         self.name = name
    #         self.age = age
    #     def func(self):
    #         print(self.name)
    # a = B('alex',80)
    # b = B('egon',20)
    # print(a)
    # print(b)
    # print(a.name)
    # print(b.name)



    5.__item__系列
    # item
    # dic = {'k':'v'}
    # print(dic['k'])
    
    
    # class Foo:
    #     def __init__(self,name):
    #         self.name=name
    #
    #     def __getitem__(self,item):
    #         return  self.__dict__[item]
    #
    #     def __setitem__(self, key, value):
    #         self.__dict__[key]=value
    #
    #     def __delitem__(self, key):
    #         print('del obj[key]时,我执行')
    #         self.__dict__.pop(key)
    
    # f = Foo('alex')
    # # f.name = ...
    # print(f['name'])    # f.__getitem__('name')
    # f['age']  = 18      # 赋值
    # print(f.age)         # 自带的语法
    # print(f['age'])     # 修改
    # f['age']  = 80
    # print(f['age'])     # 通过实现__getitem__得到的
    # del f['age']
    # print(f.age)         # 删除
    
    # class Foo:
    #     def __init__(self,name):
    #         self.name=name
    #     def __delattr__(self, item):
    #         print('del obj.key时,我执行')
    #         self.__dict__.pop(item)
    # f = Foo('alex')
    # del f.name     #相当于执行了__delattr__
    # # delattr(f,'name')

    面试题:  

    # 写一个类 定义100个对象
    # 拥有三个属性 name age sex
    # 如果两个对象的name 和 sex完全相同
    # 我们就认为这是一个对象
    # 忽略age属性
    # 做这100个对象的去重工作
    class Person:
    def __init__(self,name,age,sex):
    self.name = name
    self.age = age
    self.sex = sex
    def __hash__(self):
    # hash算法本身就存在了 且直接在python中就能调用
    # 姓名相同 性别相同的对象的hash值应该相等才行
    # 姓名性别都是字符串
    return hash(self.name+self.sex)
    def __eq__(self, other):
    if self.name == other.name and self.sex == other.sex:
    return True
    # python2.7
    # 去重 set
    # hash方法
    # set([obj,obj]) unhashable
    # hash算法 一个值 进行一系列的计算得出一个数字在一次程序执行中总是不变
    #来让每一个不同的值计算出的数字都不相等
    obj_lst = []
    obj_lst.append(Person('alex',80,'male'))
    obj_lst.append(Person('alex',70,'male'))
    obj_lst.append(Person('alex',60,'male'))
    obj_lst.append(Person('boss_jin',50,'male'))
    obj_lst.append(Person('boss_jin',40,'male'))
    obj_lst.append(Person('boss_jin',30,'male'))
    obj_lst.append(Person('nezha',20,'male'))
    obj_lst.append(Person('nezha',10,'male'))
    obj_lst = set(obj_lst)
    for obj in obj_lst:print(obj.name)
    # set对一个对象序列的去重 依赖于这个对象的两个方法 hash eq


    # 可hash顺带着写的
    # eq来做判断

    # key hash 数字 --》 内存地址 --》 value
    # set hash 数字 --》 内存地址 --》 set中的元素
    # 'aaa' hash

    # java
    # set去重 一个容器中 有相同值的内容 __eq__
    # 当你这个容器中有10000个元素的时候 我判断第10000个元素
    # hash算法
    # 'abc'
    # 'bca'
    # set对一个对象序列的去重 如何判断这两个值是否相等
    # 值a进行hash --> 存值
    # 值b进行hash --> 判断值是否相等 -相等-> 说明是一样的
    #-不相等-> 在开辟一个空间 来存放b

     








      

  • 相关阅读:
    Java_jdbc 基础笔记之六 数据库连接 (PreparedStatement)
    Java_jdbc 基础笔记之五 数据库连接 (ResultSet)
    如何在Windows Server 2008服务器中把Tomcat启动程序添加到服务中
    WebService(axis2),整合springmvc
    shiro学习
    mysql中的concat函数,concat_ws函数,concat_group函数之间的区别
    mysql几种关联的区别
    wzyxidian Scanner 与 Readable 的read()方法
    LINQ系列:LINQ to SQL Take/Skip
    LINQ系列:LINQ to SQL Concat/Union
  • 原文地址:https://www.cnblogs.com/zsdbk/p/8884468.html
Copyright © 2011-2022 走看看