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
            
  • 相关阅读:
    高进度乘法FFT优化
    Activity的四种加载模式
    异步任务AsyncTask
    利用Handler在子线程中更新UI
    Android 屏幕旋转监听
    HDOJ-1698-线段树成段更新
    HDOJ-1671-字典树
    HDOJ-1251 字典树
    python数据结构与算法
    find the lowest number location
  • 原文地址:https://www.cnblogs.com/bawu/p/8075066.html
Copyright © 2011-2022 走看看