zoukankan      html  css  js  c++  java
  • python类(2)

    #从python开始学习编程 学习笔记

    以后看书时注意一下书上表述:好像是类属性attribute,对象特性property,对象方法

    1、对于一个类下的全部个体来说,某些属性可能存在个体差异。不是所有的人类都是男,或者都是女。这个性质的值随着对象的不同而不同。

    因此,为了完整描述个体,除了共性的类属性外,我们还需要用于说明个性的对象属性。在类中,我们可以通过self来操作对象的属性。

    2、python提供了初始化对象属性的办法,python定义了一系列特殊方法,又称为魔法方法,前后有两个下划线,比如__init__()、__add__()、__dict__()等

    3、对于类的__init__()方法,python会在每次创建对象时自动调用。因此,我们可以在__init__()方法内部来初始化对象属性。

    4、除了操作对象属性外,self参数还有另外一个功能,就是能让我们在一个方法内部调用同一类的其他方法。

    5、覆盖,一般情况下,子类和父类都有的方法,子类会覆盖父类的方法,可以调用super函数保留父类方法(有点奇怪,搞两个方法干啥了??)

    class Bird:
        def chirp(self):
            print('make sound')
            
    class Chicken(Bird):
        def chirp(self):
            super().chirp()
            print('ji')
    summer=Chicken()
    print(summer.chirp())
    # make sound
    # ji
    # None
    #从结果来看,先调用父类方法,再调用子类方法

     6、一切皆对象:我们知道,list是列表的类。如果用dir(list)查看list的属性,能看到一个属性是__add__(),从样式来看,__add__()是特殊方法(魔法方法)。

    他特殊在哪呢?这个方法定义了‘+’运算符对于list对象的意义,两个list对象相加时,会进行合并列表的操作。

    (1.8).__mul__(2.8)      #5.04
    True.__or__(False)      #True
    [1,2,3]+[4,5,6]         #[1, 2, 3, 4, 5, 6]
    ['abc']+['def']         #['abc', 'def']
    'abc'.__add__('def')    #'abcdef'

    7、属性覆盖的背后

    class Bird:
        feather=True
        def chirp(self):
            print('some sound')
    class Chicken(Bird):
        fly=False
        def __init__(self,age):
            self.age=age
        def chirp(self):
            print('ji')
    summer=Chicken(2)
    print('==============> summer')
    print(summer.__dict__)
    print('==============> Chicken')
    print(Chicken.__dict__)
    print('==============> Bird')
    print(Bird.__dict__)
    print('==============> object')
    print(object.__dict__)
    ==============> summer
    {'age': 2}
    ==============> Chicken
    {'__module__': '__main__', 'fly': False, '__init__': <function Chicken.__init__ at 0x00000188456A0488>, 'chirp': <function Chicken.chirp at 0x00000188456A0510>, '__doc__': None}
    ==============> Bird
    {'__module__': '__main__', 'feather': True, 'chirp': <function Bird.chirp at 0x00000188456A0598>, '__dict__': <attribute '__dict__' of 'Bird' objects>, '__weakref__': <attribute '__weakref__' of 'Bird' objects>, '__doc__': None}
    ==============> object
    {'__repr__': <slot wrapper '__repr__' of 'object' objects>, '__hash__': <slot wrapper '__hash__' of 'object' objects>, '__str__': <slot wrapper '__str__' of 'object' objects>, '__getattribute__': <slot wrapper '__getattribute__' of 'object' objects>, '__setattr__': <slot wrapper '__setattr__' of 'object' objects>, '__delattr__': <slot wrapper '__delattr__' of 'object' objects>, '__lt__': <slot wrapper '__lt__' of 'object' objects>, '__le__': <slot wrapper '__le__' of 'object' objects>, '__eq__': <slot wrapper '__eq__' of 'object' objects>, '__ne__': <slot wrapper '__ne__' of 'object' objects>, '__gt__': <slot wrapper '__gt__' of 'object' objects>, '__ge__': <slot wrapper '__ge__' of 'object' objects>, '__init__': <slot wrapper '__init__' of 'object' objects>, '__new__': <built-in method __new__ of type object at 0x0000000059A8B580>, '__reduce_ex__': <method '__reduce_ex__' of 'object' objects>, '__reduce__': <method '__reduce__' of 'object' objects>, '__subclasshook__': <method '__subclasshook__' of 'object' objects>, '__init_subclass__': <method '__init_subclass__' of 'object' objects>, '__format__': <method '__format__' of 'object' objects>, '__sizeof__': <method '__sizeof__' of 'object' objects>, '__dir__': <method '__dir__' of 'object' objects>, '__class__': <attribute '__class__' of 'object' objects>, '__doc__': 'The most base type'}

    第一行为bird类的属性,比如feather。第二行为chicken类的属性,比如fly和__init__方法。第三行为summer对象的属性,也就是age。有一些属性,比如__doc__,并不是由我们定义的,而是由Python自动生成。此外,bird类也有父类,是object类(正如我们的bird定义,class bird(object))。这个object类是Python中所有类的父类。

    print(dir(summer))
    ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'chirp', 'feather', 'fly']

    如果我们用内置函数dir来查看summer的属性的话,可以看到summer对象包含了全部四个部分,也就是说,Python中的属性是分层定义的,比如这里分为object/bird/chicken/summer这四层。当我们需要调用某个属性的时候,Python会一层层向上遍历,直到找到那个属性。(某个属性可能出现在不同的层被重复定义,Python向上的过程中,会选取先遇到的那一个,也就是比较低层的属性定义)。这正是属性覆盖的原理所在。由于对象不需要重复存储其祖先类的属性,所以分层管理的机制可以节省存储空间。

    值得注意的是,上面都是调用属性的操作,如果进行赋值,那么python就不会分层深入查找了。

    autumn=Chicken(3)
    autumn.feather=False
    print(summer.feather)  #True
    print(autumn.__dict__) #{'age': 3, 'feather': False}

    因此,python在为属性赋值时,只会搜索对象本身的__dict__,如果找不到对应属性,则将在__dict__中增加。在类 定义的方法中,如果用self引用对象,

    也会遵守相同规则。

    此外,我们可以不依赖继承关系,直接去操作某个祖先类的属性。

    Bird.feather=3

    8、特性

     同一个对象的不同属性之间可能存在依赖关系。当某个属性被修改时,我们希望依赖于该属性的其他属性也同时变化。这时,我们不能通过__dict__的静态词典

    方式来存储属性。Python提供了多种即时生成属性的方法。其中一种称为特性(property)。特性是特殊的属性。

    class Bird:
        feather=True
    class Chicken(Bird):
        fly=False
        def __init__(self,age):
            self.age=age
        def get_adult(self):
            if self.age>1.0:
                return True
            else:
                return False
        adult=property(get_adult) #property is bulit-in  
    summer=Chicken(2)
    print(summer.adult)  #True
    print(summer.get_adult())#True
    summer.age=0.5
    print(summer.adult)  #False
    print(summer.get_adult()) #False
    class Bird:
        feather=True
    class Chicken(Bird):
        fly=False
        def __init__(self,age):
            self.age=age
        @property
        def get_adult(self):
            if self.age>1.0:
                return True
            else:
                return False
    summer=Chicken(2)
    print(summer.get_adult)#True
    summer.age=0.5
    print(summer.get_adult) #False

     9、比较如下代码区别:

    class Bird:
        feather=True
        age=2
        def __init__(self,name):
            self.name=name
    class Chicken(Bird):
        fly=False
        def __init__(self,age):
            self.age=age
        @property
        def get_adult(self):
            if self.age>1.0:
                return True
            else:
                return False
    summer=Chicken(2)
    print(summer.get_adult)#True
    summer.age=0.5
    print(summer.get_adult) #False
    class Bird:
        feather=True
        age=2
        def __init__(self,name):
            self.name=name
    class Chicken(Bird):
        fly=False
    #     def __init__(self,age):
    #         self.age=age
        @property
        def get_adult(self):
            if self.age>1.0:
                return True
            else:
                return False
    summer=Chicken()
    print(summer.get_adult)
    summer.age=0.5
    print(summer.get_adult)
    #如果用self引用对象,本层没有,好像会找到父类那一层去。
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-48-496496d87f7c> in <module>()
         14         else:
         15             return False
    ---> 16 summer=Chicken()
         17 print(summer.get_adult)#True
         18 summer.age=0.5
    
    TypeError: __init__() missing 1 required positional argument: 'name'
    class Bird:
        feather=True
        age=2
        def __init__(self,name):
            self.name=name
    class Chicken(Bird):
        fly=False
    #     def __init__(self,age):
    #         self.age=age
        @property
        def get_adult(self):
            if self.age>1.0:
                return True
            else:
                return False
    summer=Chicken(2)
    print(summer.get_adult)#True
    summer.age=0.5
    print(summer.get_adult) #False
    class Bird:
        feather=True
        age=2
        def __init__(self,name):
            self.name=name
    class Chicken(Bird):
        fly=False
        age=2              #增加age=2
    #     def __init__(self,age):
    #         self.age=age
        @property
        def get_adult(self):
            if self.age>1.0:
                return True
            else:
                return False
    summer=Chicken()
    print(summer.get_adult)
    summer.age=0.5
    print(summer.get_adult)
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-50-9ac0fb881573> in <module>()
         15         else:
         16             return False
    ---> 17 summer=Chicken()
         18 print(summer.get_adult)#True
         19 summer.age=0.5
    
    TypeError: __init__() missing 1 required positional argument: 'name'
    class Bird:
        feather=True
        age=2
    class Chicken(Bird):
        fly=False
        @property
        def get_adult(self):
            if Bird.age>1.0:
                return True
            else:
                return False
    summer=Chicken()
    print(summer.get_adult)#True
    summer.age=0.5
    print(summer.get_adult) #True

     与上面类似,修改了实例特性,但是类属性没有修改,通过类方法调用的时候修改不起 作用,类属性没有修改。

    class A:
        x='jim'
        @classmethod
        def run(cls):
            y=cls.x
            print('{} is running'.format(y))
            return y
    class B(A):
        pass
    b=B()
    print(b.run())
    b.x='yang'
    print(b.x)
    print(A.x)
    print(b.run())  
    #jim is running
    #jim
    #yang
    #jim
    #jim is running
    #jim

    10、特性使用内置函数property()来创建。property()最多可以加载四个参数。前三个参数为函数,分别用于设置获取、修改和删除特性是,Python应该执行的操作。最后一个参数为特性的文档,可以为一个字符串,起说明作用。

    class Num:
        def __init__(self,value):
            self.value=value
        def get_neg(self):
            return -self.value
        def set_neg(self,value):
            self.value=-value
        def del_neg(self):
            print('value also deleted')
            del self.value
        neg=property(get_neg,set_neg,del_neg,'i am negative')
    x=Num(1.2)
    print(x.neg)  # -1.2
    x.neg=-22
    print(x.value)  #22
    print(Num.neg.__doc__) #i am negative
    del x.neg       #value also deleted
            
  • 相关阅读:
    Code Forces 650 C Table Compression(并查集)
    Code Forces 645B Mischievous Mess Makers
    POJ 3735 Training little cats(矩阵快速幂)
    POJ 3233 Matrix Power Series(矩阵快速幂)
    PAT 1026 Table Tennis (30)
    ZOJ 3609 Modular Inverse
    Java实现 LeetCode 746 使用最小花费爬楼梯(递推)
    Java实现 LeetCode 745 前缀和后缀搜索(使用Hash代替字典树)
    Java实现 LeetCode 745 前缀和后缀搜索(使用Hash代替字典树)
    Java实现 LeetCode 745 前缀和后缀搜索(使用Hash代替字典树)
  • 原文地址:https://www.cnblogs.com/bawu/p/8075066.html
Copyright © 2011-2022 走看看