• 第十章 初识面向对象(续)


    1.封装                                                         

    什么是封装:

    广义上的封装:把变量和函数都放在类中(例:人狗大战中,将狗咬人的函数放到dog类中)

    狭义上的封装:把一些变量或者方法隐藏起来,不对外公开

      公有的:静态属性,动态属性(方法),对象属性

      私有的:__名字

    私有静态属性

    # 例:
    class Person:
        __country = '中国' # 私有的静态属性
        # print(__country) # 执行文件会输出结果,因为定义类的时候会开辟一块内存空间存储类中的名字
    
    print(Person.__country)
    #     print(Person.__country)
    # AttributeError: type object 'Person' has no attribute '__country'
    # 说明:私有的名字 只能在类的内部使用,不能在类的外部使用
    
    print(Person.__dict__)
    # {'__module__': '__main__', '_Person__country': '中国', '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
    print(Person._Person__country)
    # 中国
    # 说明:如果非要在类的外部调用一个私有的名字,name必须是在私有的名字前面加_类名__私有的名字
    # *****注意:不能使用上面这种方式去调用私有的变量*****
    #
    Person.__name = 'xxx'
    print(Person.__name)
    # xxx
    print(Person.__dict__)
    # {'__module__': '__main__', '_Person__country': '中国', '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, '__name': 'xxx'}
    # 说明:在类的外部不能定义一个私有变量
    # 私有的变量:
    # 在类的内部 如果使用__变量的形式会发生变形,python会自动的为你加上_类名

     私有的对象属性

    # 私有的对象属性
    class Person:
        __country = '中国'
        def __init__(self, name, pwd):
            self.name = name
            self.__pwd = pwd # 私有的对象属性
    alex = Person('alex', 'alex123')
    # print(alex.__pwd)
    # #     print(alex.__pwd)
    # # AttributeError: 'Person' object has no attribute '__pwd'
    
    # 私有的对象属性的使用 -- 类中的登录方法
    class Person:
        __country = '中国'
        def __init__(self, name, pwd):
            self.name = name
            self.__pwd = pwd # 私有的对象属性
        def login(self):
            if self.name == 'alex' and self.__pwd == 'alex123':
                print('登录成功')
    alex = Person('alex', 'alex123')
    alex.login()
    # 登录成功

    私有的方法

    # 私有的方法
    class Person:
        def __init__(self):pass
        def __eat(self):
            print('eating')
    
    alex = Person()
    # alex.__eat()
    #     alex.__eat()
    # AttributeError: 'Person' object has no attribute '__eat'
    # 说明:不希望类中的一些方法,对外提供服务,但可以对内提供服务
    # 使用场景:用户注册,进行密码转换

    总结:在静态属性、对象属性、方法(动态属性)前面加上双下划线都会变成私有的

              私有的特点就是只能在类的内部调用,不能在类的外部使用

    测试题

    # 测试题:实例化s,打印结果是什么
    # 1.有关方法继承的练习
    # 说明:就近原则,现在自己的命名空间中找,然后到父类中找
    class Foo:
        def __init__(self):
            self.func()
        def func(self):
            print('in Foo')
    class Son(Foo):
        def func(self):
            print('in son')
    s = Son()
    # in son
    
    # 2.有关方私有法继承的练习
    class Foo:
        def __init__(self):
            self.__func() # self._Foo_func(没有)
        def __func(self):
            print('in Foo')
    
    class Son(Foo):
        def __func(self): # _Son_func
            print('in son')
    
    s = Son()
    # in Foo

    2.类中的装饰器方法                                             

    三个面向对象的内置函数 -- 三个装饰器函数

    classmethod、staticmethod、property

    2.1 property

    未使用property和使用property的类的比较

    # 例 -  圆形类:
    # 未使用property
    from cmath import pi
    class Cricle:
        def __init__(self,r):
            self.r = r
        def area(self):
            return self.r ** 2 * pi
        def perimeter(self):
            return self.r * 2 * pi
    c = Cricle(3)
    print(c.area())
    # 28.274333882308138
    print(c.perimeter())
    # 18.84955592153876
    
    # 方法 动词 -- 动作或者技能
    # 名词 圆的面积 圆的周长 圆的半径
    # 将一个函数伪装成为属性@property
    # 一旦一个方法添加了@property,就不能使用c.area()调用了
    from cmath import pi
    class Cricle:
        def __init__(self,r):
            self.r = r
        @property
        def area(self):
            return self.r ** 2 * pi
        @property
        def perimeter(self):
            return self.r * 2 * pi
    
    c = Cricle(3)
    print(c.area)
    # 28.274333882308138
    print(c.perimeter)
    # 18.84955592153876

    练习1:编写类,求房间的表面积和体积

    # 练习:已知房间的长宽高,计算表面积和体积
    class Room:
        def __init__(self, length, width , height):
            self.length = length
            self.width = width
            self.height = height
        @property
        def area(self):
            return (self.length * self.width + self.length * self.height + self.width * self.height) * 2
        @property
        def volume(self):
            return self.length * self.width * self.height
    
    room = Room(3, 5, 3)
    print(room.area)
    # 78
    print(room.volume)
    # 45

    练习2:property结合__私有的名字,setter更新私有对象属性,deleter删除私有对象属性

    # property __私有的名字
    # 商场打折行为
    class Goods:
        def __init__(self,price, discount):
            self.__price = price
            self.discount = discount
        @property #添加property因为不添加括号了,所以不能添加参数了
        def price(self):
            return self.__price * self.discount
        @price.setter  # 使用前提,必须已经price方法,并使用property进行隐藏
        def price(self, newprice):
            self.__price = newprice
        @price.deleter # 删除price方法,但是并不常用
        def price(self):
            del self.__price
    apple = Goods(8, 0.7)
    print(apple.price)
    # 5.6
    apple.price = 10
    print(apple.price)
    # 7.0
    print(apple.__dict__)
    # {'_Goods__price': 10, 'discount': 0.7}
    del apple.price
    print(apple.__dict__)
    {'discount': 0.7}
    print(apple.price)
    #     return self.__price * self.discount
    # AttributeError: 'Goods' object has no attribute '_Goods__price'

    2.2classmethod类方法

    class Person:
        Country = '中国人'
        def func(self):
            print('当前的角色的国籍是%s' % Person.Country)
    
    alex = Person()
    alex.func()
    # 当前的角色的国籍是中国人
    Person.func()
    #     Person.func()
    # TypeError: func() missing 1 required positional argument: 'self'
    
    # 类方法
    class Person:
        Country = '中国人'
        @classmethod   # 把func变成一个类方法,这样就不需要实例化对象才能调用类中的方法
        def func(cls): # cls是指向类的内存空间
            print('当前的角色的国籍是%s' % Person.Country)
    
    Person.func()
    # 当前的角色的国籍是中国人
    # 说明: 如果某一个类中的方法 并没有用到这个类的实例中的具体属性
    # 只是用到了类中的静态变量 就使用类方法

    2.3staticmethod静态方法

    如果一个方法既不会用到对象中的属性,也不会用到类中的属性,就应该被定义成为一个静态方法

    # 静态方法staticmethod
    class Student:
        @staticmethod
        def login():
            name = input('name: ')
            pwd = input('pwd: ')
            if name == '' and pwd == '':
                print('实例化')
    
    Student.login()
    # name: alex
    # pwd: alex123
    # 使用场景:在没有创建student对象的时候,进行学员登录
    # 如果登录成功,再进行实例化
    一鼓作气,再而衰,三而竭。
  • 相关阅读:
    loadrunner Message函数
    loadrunner informational函数
    loadrunner database函数
    loadrunner CommandLine函数
    loadrunner重播函数
    loadrnner header函数
    KVM虚拟机的xml配置文件
    cinder-backup驱动配置
    Areon 删除linux软raid方法
    Mdadm命令详解
  • 原文地址:https://www.cnblogs.com/gongniue/p/9077191.html
Copyright © 2020-2023  润新知