• 二十四. Python基础(24)--封装


    二十四. Python基础(24)--封装

    ● 知识结构

     

    ● 类属性和__slots__属性

    class Student(object):

        grade = 3 # 也可以写在__slots__属性下面__slots__下面

     

        def __init__(self, name, age, hobby):

            self.name=name

            self.age=age

            # self.hobby=hobby # 如果定义了这个对象属性, 会抛出异常: AttributeError: 'Student' object has no attribute 'hobby'

     

    a=Student('Arroz', 22,'swimming')

    b=Student('Paul', 30,'skating')

    print(Student.grade) # 3

    print(a.grade) # 3, 类和对象都可以访问静态属性/类属性

    a.grade = 5 # 此时没有定义__slos__属性, 类属性grade可写

    print(a.grade) # 5

    print(b.grade)

    # python的类变量和C++的静态变量不同,并不是由类的所有对象共享。

    # 如果是在C++, 如果某一个对象修改了静态属性, 其它对象的静态属性(实际上是同一个静态属性)也将改变

    print(a.__dict__) # {'name': 'Arroz', 'age': 22, 'grade': 5}

     

    class Student(object):

        grade = 3 # 也可以写在__slots__属性下面__slots__下面

        __slots__ = ['name', 'age'] # 限定可以定义的对象属性为name, age

     

        def __init__(self, name, age, hobby):

            self.name=name

            self.age=age

            # self.hobby=hobby # 如果定义了这个对象属性, 会抛出异常: AttributeError: 'Student' object has no attribute 'hobby'

     

    a=Student('Arroz', 22,'swimming')

    b=Student('Paul', 30,'skating')

    print(Student.grade)

    print(a.grade) # 类和对象都可以访问静态属性/类属性

    #a.grade = 5 # 此时定义了__slos__属性, 类属性grade只读: # a.grade = 5 # 此时没有定义__slos__属性, 类属性grade可写

    print(a.grade)

    print(b.grade)

    # print(a.__dict__) # 'Student' object has no attribute '__dict__'

    print(dir(a))

    # 如果在一个类中添加了__slots__属性,那么这个类的实例将不会拥有__dict__属性

    # 但是dir()仍然可以找到并列出它的实例所有有效属性。

     

    ● 类的特性

    class Shop:

        discount = 0.5 # 打五折

     

        def __init__(self,name, price):

            self.name = name

            self.__price = price

     

        @property # The @property decorator marks the getter method of a property (@property装饰器标志了一个特性的getter方法)

        def price(self):

            return self.__price * Shop.discount

     

        @price.setter

        def price(self, new_price):

            self.__price = new_price

     

        @price.deleter

        def price(self):

            del self.__price

     

    apple = Shop('apple', 5)

    # print(apple.__price) # AttributeError: 'Shop' object has no attribute '__price'

    print('discount:', Shop.discount) #discount: 0.5

    print('discount:', apple.discount) #discount: 0.5

    print('__price:', apple._Shop__price) # __price: 5

    print(apple.price) # 3.75 (调用getter方法)

    apple.price = 6 # (因为有等号, 所有调用setter方法)

    print(apple.price) # 4.5

    print(apple.__dict__) # {'name': 'apple', '_Shop__price': 6}

    del apple.price # 调用deleter方法

    print(apple.__dict__) # {'name': 'apple'}

    # 有关删除属性

    class A:

        pass

     

    a = A()

    a.name = 'Arroz'

    print(a.name) # Arroz

    del a.name # 删除属性

    # print(a.name) # AttributeError: 'A' object has no attribute 'name'

     

    ● 什么时候用静态方法

    class Parent:

        def __method1(self):

            print('Foo')

     

    class Son(Parent):

        def __method2(self):

            print('Son')

     

        def fun(self):

            return self.__method2() # return关键字可以省略, 返回值, __method2()时中间结果

     

    son = Son()

    son.fun() # Son

     

    # 什么时候用私有方法?

    #1.有一些方法的返回值只是用来作为中间结果

    #2.父类的方法不希望子类继承

     

    ● 静态方法 & 类方法

    class Foo:

        val1=5

        def __init__(self, value):

            self.val2 = value

     

        @staticmethod

        def staticfunc():

            Foo.val1 = 10 # 可以访问类属性

            # 无法访问对象属性

     

        @classmethod

        def classfunc(cls):

            cls.val1 = 15 # 可以访问类属性

            # 无法访问对象属性

     

     

    Foo.staticfunc()

    print(Foo.val1) #10

    Foo.classfunc()

    print(Foo.val1) #15

    静态方法 类方法都可以操作类本身,为什么还要在发明一个类方法?

    静态方法是通过类名来操作类属性的, 这是写死在程序中, 而类方法是通过类型参数来操作类属性的

    如果子类继承了使用静态方法的类,那么子类继承的静态方法还是在操作父类, 子类需要重写静态方法才能操作子类(也就是需要重写成用子类名来操作类属性)

    类方法如果被继承, 那么类型参数会传入子类本身, 也因此, 子类不需要重写类方法(因为cls指本类)

     

    ● 命名元祖

    #命名元祖: 没有方法、 并且不能改变属性值的类

    from collections import namedtuple

    Point = namedtuple('point',['x','y'])

    t1 = Point(1,2)

    print(t1.x, t1.y)

    # t1.x=3 # AttributeError: can't set attribute

     

  • 相关阅读:
    铁轨
    POJ 2385 -- Apple Catching
    POJ 3258 -- River Hopscotch
    POJ 1469 -- COURSES (二分匹配)
    POJ 2349 -- Arctic Network
    最小生成树
    NOIP200703守望者的逃离
    NOIP200706字符串的展开
    POJ 1036 -- Gangsters
    POJ 1952 -- BUY LOW, BUY LOWER
  • 原文地址:https://www.cnblogs.com/ArrozZhu/p/8396577.html
Copyright © 2020-2023  润新知