zoukankan      html  css  js  c++  java
  • day 26-1 property、绑定与非绑定方法

    property

    property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值;就是把一个函数属性的访问方式变成像访问数据属性的方式一样。

    我们首先来看一个对比效果

    例一:在调用 bmi 函数的时候需要加括号的,可是我们往往需要另一种调用方法——不想加括号

    class people():
        def __init__(self, name, height, weight):
            self.name = name
            self.height = height
            self.weight = weight
    
        def bmi(self):
            return self.weight / (self.height ** 2)
    
    
    p = people('ysg', 1.8, 75)
    print(p.bmi())
    # 结果:23.148148148148145

    例二:使用 property 后,则调用不需要在使用括号了

    class people():
        def __init__(self, name, height, weight):
            self.name = name
            self.height = height
            self.weight = weight
    
        @property
        def bmi(self):
            return self.weight / (self.height ** 2)
    
    
    p = people('ysg', 1.8, 75)
    print(p.bmi)
    # 结果:23.148148148148145
    # 使用加括号调用的会报错:TypeError: 'float' object is not callable
    property 的其他用法,并不常用
    前提条件
    class people():
        def __init__(self, name):
            self.__name = name
    
        @property
        def name(self):
            return self.__name
    
    
    p = people('ysg')
    print(p.name)
    setter、deleter 的使用
    class people():
        def __init__(self, name):
            self.__name = name
    
        @property
        def name(self):
            return self.__name
    
        @name.setter
        def name(self, val):
            if not isinstance(val, str):
                print('格式不是 str,不允许被修改')
                return
            self.__name = val
        @name.deleter
        def name(self):
            print('不允许被删除')
    
    
    修改
    p = people('ysg')
    p.name = 'ysging'
    print(p.name)
    结果:ysging
    
    p.name = 213
    print(p.name)
    结果:
    格式不是 str,不允许被修改
    ysg
    
    删除
    del p.name
    print(p.name)
    结果:
    不允许被删除
    ysg
    property 意义在于:将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的 name 是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

    绑定方法

    在类内部定义的函数,分为两大类

    一:绑定方法

      绑定给谁,就应该由谁来调用,谁来调用就会把调用者当作第一个参数自动传入

        绑定对象的方法:在类内定义的没有被任何装饰器修饰的

        绑定到类的方法:在类内定义的被装饰器 classmethod 修饰的方法

    二:非绑定方法

      不与类或者对象绑定,没有自动传值
      就是在类中定义一个普通的函数或工具,对象和类都可以调用,都需要传值

    绑定对象的方法

    class Foo():
        def __init__(self, name):
            self.name = name
    
        def tell(self):
            print('this is %s' % self.name)
    
        @classmethod
        def func(cls):
            print()
    
    f = Foo('ysg')
    f.tell()            # this is ysg
    print(f.tell)       # <bound method Foo.tell of <__main__.Foo object at 0x000001E5BED2F390>>
    print(Foo.tell)     # <function Foo.tell at 0x000001E5BED31268>
    Foo.tell(f)         # 使用类来调用  this is ysg

    绑定到类的方法

    class Foo():
        def __init__(self, name):
            self.name = name
    
        @classmethod
        def func(cls):
            print(cls)
    
    
    
    f = Foo('ysg')
    print(Foo.func)         # <bound method Foo.func of <class '__main__.Foo'>>
    Foo.func()              # <class '__main__.Foo'>
    print(Foo)              # <class '__main__.Foo'>

    非绑定方法

    class Foo():
        def __init__(self, name):
            self.name = name
    
        @staticmethod
        def func(x, y):
            print(x + y)
    
    
    f = Foo('ysg')
    print(Foo.func)     # <function Foo.func at 0x0000021B45FE1268>
    print(f.func)       # <function Foo.func at 0x0000021B45FE1268>
    f.func(1, 2)        # 3
    Foo.func(1, 2)      # 3

    使用场景

    总结:使用哪种方法,取决于函数体的逻辑来进行判断应该传什么参数。

    例子:绑定到对象

    class People():
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        def tell(self):
            print('姓名:{0},年龄:{1},性别:{2}'.format(self.name, self.age, self.sex))
    
    
    p = People('ysg', 21, 'man')
    p.tell()        # 姓名:ysg,年龄:21,性别:man

    例子:绑定到类

    前提条件,从配置文件中取值

    configs.py
    
    name = 'ysging'
    age = 15
    sex = 'man'
    import configs
    class People():
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        def tell_info(self):
            print('姓名:{0},年龄:{1},性别:{2}'.format(self.name, self.age, self.sex))
    
        @classmethod
        def tell(cls):
            p = cls(
                configs.name,
                configs.age,
                configs.sex
            )
            return p
    
    
    p = People.tell()
    p.tell_info()       #姓名:ysging,年龄:15,性别:man

    例子:非绑定方法,给每一个实例分配 id

    import time
    import hashlib
    
    
    class People():
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
            self.id = self.ids()
    
        @staticmethod
        def ids():
            time.sleep(0.01)
            m = hashlib.md5(str(time.time()).encode('utf-8'))
            return m.hexdigest()
    
    
    p = People('ysg1', 21, 'man')
    p2 = People('ysg2', 22, 'man')
    p3 = People('ysg3', 23, 'man')
    
    print(p.id)   # 44261d399ba9650c628cb8d189ffdd0b
    print(p2.id)  # 2c7270c27984119c7cf39e9d575f07bd
    print(p3.id)  # 4c386111edf4f641f7c35bb855d1551a
  • 相关阅读:
    UOJ179
    Codeforces603E
    洛谷P4219
    Vijos1655
    JS对象 四舍五入round() round() 方法可把一个数字四舍五入为最接近的整数。 语法: Math.round(x)
    JS对象 向下取整floor() floor() 方法可对一个数进行向下取整。 语法: Math.floor(x)
    JS对象 向上取整ceil() ceil() 方法可对一个数进行向上取整。 语法: Math.ceil(x) 注意:它返回的是大于或等于x,并且与x最接近的整数。
    JS对象 神奇的Math对象,提供对数据的数学计算。注意:Math 对象是一个固有的对象,无需创建它,直接把 Math 作为对象使用就可以调用其所有属性和方法。这是它与Date,String对象的区别
    JS对象 提取指定数目的字符substr() substr() 方法从字符串中提取从 startPos位置开始的指定数目的字符串。
    JS对象 substring() 方法用于提取字符串中介于两个指定下标之间的字符。
  • 原文地址:https://www.cnblogs.com/ysging/p/12055905.html
Copyright © 2011-2022 走看看