zoukankan      html  css  js  c++  java
  • Python基础-面向对象进阶

    面向对象进阶

    一 类中的装饰器方法  classmethod staticmethod property

    1.1 property

    一般情况下,方法都是动词。指某一类事物的动作

    在计算圆形的周长和面积的时候,他们应该是圆形的属性,但是这里确是一个方法。这不符合python面向对象(能够完全区分属性和方法)的理念。

    所以我们可以用一个装饰器去将一个属性性质的函数,装饰成一个属性。可以以调用属性的方式去调用他。

    from math import pi
    class Circle:
        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 = Circle(3)
    print(c.area)
    print(c.perimeter)

    property __私有的名字

    计算商品的折后价

    class Goods:
        def __init__(self, price, discount):
            self.price = price
            self.discount = discount
    
        def real_price(self):
            return self.price * self.discount
    
    apple = Goods(8, 0.7)
    print(apple.real_price())   ## 折后价也是商品的属性,我们应该用调用属性的方式去调用它。
    class Goods:
        def __init__(self, price, discount):
            self.__price = price   # 隐藏真实价格
            self.discount = discount
    
        @property
        def price(self):   ## 与真实价格名字不冲突
            return self.__price * self.discount
    
    apple = Goods(8, 0.7)
    print(apple.price)  # 不需要括号了  # 可是我们如何更改原始的价格呢 也不可以传参数了



    # 这种情况下,如果苹果价格变了呢?我们如何给__price赋值呢

    setter (很少用)

    class Goods:
        def __init__(self, price, discount):
            self.__price = price
            self.discount = discount
    
        @property
        def price(self):   ## 与真实价格名字不冲突
            return self.__price * self.discount
    
        @price.setter    
        def price(self,newprice):  # 要设一个property装饰的函数的同名函数,并使用@函数名.setter  就可以接受更改变量。
            # print(newprice)
            self.__price = newprice
    
    apple = Goods(8, 0.7)
    print(apple.price)  # 不需要括号了
    apple.price = 10  # 可以穿参数 ,更改价格
    print(apple.price)

    deleter (很少用)

    class Goods:
        def __init__(self, price, discount):
            self.__price = price
            self.discount = discount
    
        @property
        def price(self):   ## 与真实价格名字不冲突
            return self.__price * self.discount
    
        @price.setter
        def price(self,newprice):  # 要设一个property装饰的函数的同名函数,并使用@函数名.setter  就可以接受更改变量。
            # print(newprice)
            self.__price = newprice
    
        @price.deleter
        def price(self):
            del self.__price
    
    apple = Goods(8, 0.7)
    print(apple.price)  # 不需要括号了
    apple.price = 10  # 可以穿参数 ,更改价格
    print(apple.price)
    del apple.price
    print(apple.price) # AttributeError: 'Goods' object has no attribute '_Goods__price'

    1.2  classmethod

    class Person:
        Country = 'chinese'
    
        @classmethod  # 把func 变成了一个类的方法
        def func(cls):   #不需要穿一个self ,传一个cls 指向类的内存空间
            print('当前角色的国籍是%s'%Person.Country)
    
    Person.func()
    
    如果某一个类中的方法 并没有用到这个类的实例中的具体属性
    只是用到了类中的静态变量,就使用类方法 classmethod

    1.3 staticmethod

    class Student:
        @staticmethod  #在login方法中使用静态方法的装饰器,login方法就不需要传参数进去了。
        def login():
            name = input('name: ')
            pwd = input('pwd: ')
            if name == '' and pwd == '':
                print('123')

    Student.login()

    如果一个方法,既不会用到对象中的属性也不会用到类中的属性(不需要传参),

    就应该定义为静态方法 @staticmethod

    二 反射 *****

    2.1 反射的概念

    2.1.1 什么叫反射

    通过字符串数据类型的变量名来访问变量的值,就叫做反射

    2.1.2 python面向对象中的反射

    通过字符串的形式操作对象相关的属性。python中一切皆对象(都可以使用反射)

    2.2 类名反射静态属性 和 对象名反射方法

    # 类名 反射 静态属性
    # 对象名 反射 对象属性 和 方法
    # 类名 反射 静态属性
    # 对象名 反射 对象属性 和 方法
    # 模块 反射 模块中的名字
    # 反射 自己所在文件中的名字
    
    # x.y 这样的形式 都可以用反射
    
    print('aaa'.startswith)
    print('aaa'.startswith('a'))
    # 'startswith'
    ret = getattr('aaa','startswith')
    print(ret)
    print(ret('a'))
    class Person:
        role = 'Person'
        def __init__(self,name):
            self.name = name
        def eat(self):print('eating')
        def drink(self):print('drinking')
        def play(self):print('playing')
        def sleep(self):print('sleepping')
    
    alex = Person('alex')
    alex.name
    print(getattr(alex,'name'))  ## 获取属性,不需要加括号
    print(getattr(Person,'role'))  ## 获取属性
    
    while True:
        inp = input('>>>')
        if hasattr(alex,inp):   ## 先用 hasattr 判断方法是否存在
            getattr(alex,inp)()   ## 然后用 getattr 执行这个存在的方法    获取方法 需要加括号执行这个方法

    # 首先 使用getattr取获取一个名字,如果在这个对象的命名空间中没有这个名字 会报错
    # getattr的反射好伴侣 hasattr
    # 如果使用getattr取获取一个方法,那么只能拿到这个方法的内存地址 加上括号就是执行,当然,括号里的参数可以照传不误
    # 如果getattr获取一个属性,那么直接使用反射就可以获取到值

    2.3 模块反射模块中的名字 和 反射自己所在文件中的名字

    # 模块 反射 模块中的名字

    什么是模块?模块就是一个py文件 

    模块导入,就是执行这个文件

    写一个模块

    def func1():
        print('my module')
    mymodule.py

    导入模块,反射模块中的名字

    import mymodule
    import time
    
    mymodule.func1()
    time.sleep(0.5)
    # print(mymodule.money)
    getattr(mymodule,'func1')()
    # 反射 自己所在文件中的名字
    import sys
    
    value = 123
    print(sys.modules)
    # {'builtins': <module 'builtins' (built-in)>, 'sys': <module 'sys' (built-in)>, '_frozen_importlib': <module '_frozen_importlib' (frozen)>, '_imp': <module '_imp' (built-in)>, '_warnings': <module '_warnings' (built-in)>, '_thread': <module '_thread' (built-in)>, '_weakref': <module '_weakref' (built-in)>, '_frozen_importlib_external': <module '_frozen_importlib_external' (frozen)>, '_io': <module 'io' (built-in)>, 'marshal': <module 'marshal' (built-in)>, 'posix': <module 'posix' (built-in)>, 'zipimport': <module 'zipimport' (built-in)>, 'encodings': <module 'encodings' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/encodings/__init__.py'>, 'codecs': <module 'codecs' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/codecs.py'>, '_codecs': <module '_codecs' (built-in)>, 'encodings.aliases': <module 'encodings.aliases' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/encodings/aliases.py'>, 'encodings.utf_8': <module 'encodings.utf_8' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/encodings/utf_8.py'>, '_signal': <module '_signal' (built-in)>, '__main__': <module '__main__' from '/Users/wph/PycharmProjects/learn/Day7/test.py'>, 'encodings.latin_1': <module 'encodings.latin_1' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/encodings/latin_1.py'>, 'io': <module 'io' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/io.py'>, 'abc': <module 'abc' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/abc.py'>, '_weakrefset': <module '_weakrefset' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_weakrefset.py'>, 'site': <module 'site' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site.py'>, 'os': <module 'os' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/os.py'>, 'errno': <module 'errno' (built-in)>, 'stat': <module 'stat' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/stat.py'>, '_stat': <module '_stat' (built-in)>, 'posixpath': <module 'posixpath' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/posixpath.py'>, 'genericpath': <module 'genericpath' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/genericpath.py'>, 'os.path': <module 'posixpath' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/posixpath.py'>, '_collections_abc': <module '_collections_abc' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_collections_abc.py'>, '_sitebuiltins': <module '_sitebuiltins' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_sitebuiltins.py'>, 'sysconfig': <module 'sysconfig' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/sysconfig.py'>, '_sysconfigdata_m_darwin_darwin': <module '_sysconfigdata_m_darwin_darwin' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_sysconfigdata_m_darwin_darwin.py'>, '_osx_support': <module '_osx_support' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_osx_support.py'>, 're': <module 're' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/re.py'>, 'enum': <module 'enum' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/enum.py'>, 'types': <module 'types' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/types.py'>, 'functools': <module 'functools' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/functools.py'>, '_functools': <module '_functools' (built-in)>, 'collections': <module 'collections' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/collections/__init__.py'>, 'operator': <module 'operator' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/operator.py'>, '_operator': <module '_operator' (built-in)>, 'keyword': <module 'keyword' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/keyword.py'>, 'heapq': <module 'heapq' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/heapq.py'>, '_heapq': <module '_heapq' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload/_heapq.cpython-36m-darwin.so'>, 'itertools': <module 'itertools' (built-in)>, 'reprlib': <module 'reprlib' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/reprlib.py'>, '_collections': <module '_collections' (built-in)>, 'weakref': <module 'weakref' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/weakref.py'>, 'collections.abc': <module 'collections.abc' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/collections/abc.py'>, 'sre_compile': <module 'sre_compile' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/sre_compile.py'>, '_sre': <module '_sre' (built-in)>, 'sre_parse': <module 'sre_parse' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/sre_parse.py'>, 'sre_constants': <module 'sre_constants' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/sre_constants.py'>, '_locale': <module '_locale' (built-in)>, 'copyreg': <module 'copyreg' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/copyreg.py'>, '_bootlocale': <module '_bootlocale' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_bootlocale.py'>, 'encodings.ascii': <module 'encodings.ascii' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/encodings/ascii.py'>, 'sitecustomize': <module 'sitecustomize' from '/Applications/PyCharm.app/Contents/helpers/pycharm_matplotlib_backend/sitecustomize.py'>}
    
    print(sys.modules['__main__'])  # 拿到当前模块的名字  就是本文件的文件名
    print(getattr(sys.modules['__main__'], 'value'))

    三 isinstance和issubclass

    isinstance(obj,cls)检查是否obj是否是类 cls 的对象

    class Foo(object):
         pass
      
    obj = Foo()
      
    isinstance(obj, Foo)  # print  True

    issubclass(sub, super)检查sub类是否是 super 类的派生类 

    class Foo(object):
        pass
     
    class Bar(Foo):
        pass
     
    issubclass(Bar, Foo)

    __new__

    # __new__    构造方法 创建一个对象
    # __init__   初始化方法
    
    class Foo:
        def __new__(cls, *args, **kwargs):
            print('执行我啦')
            obj = object.__new__(cls)
            print(obj)
            return obj
        def __init__(self):
            print('222222222',self)
    
    Foo()
    
    # 先执行new方法,object.new()
    # 再执行init
    
    # Foo()  --> python解释器接收到你的python代码
    # python解释器替你去做了很多操作
    # 包括 主动帮助你 调用 new方法 去创造一个对象 —— 开辟内存空间 —— python语言封装了开辟内存的工作
    # object的new方法里 —— 帮你创造了对象
    # 调用init用到的self参数 就是new帮你创造的对象

    单例模式

    # 单例模式 : 某一类 只有一个实例
    class Person:
        __isinstance = None
        def __new__(cls, *args, **kwargs):
            if not cls.__isinstance :
                obj = object.__new__(cls)
                cls.__isinstance = obj
            return cls.__isinstance
        def __init__(self,name):
            self.name = name
    
    alex = Person('alex')
    alex.age = 18
    egon = Person('egon')
    print(egon.age)
    print(id(alex))
    print(id(egon))
    print(alex.name)  # egon
    print(egon.name)  # egon
    __new__生孩子
    类 : 生一个小孩__new__ 给这个小孩穿衣服 __init__
    单例模式下的类 : 只有一个小孩

    内置方法str

    class Person:
        def __init__(self,name):
            self.name = name
        def __str__(self):
            return 'a object of Person named %s'%self.name
        # def __hash__(self):
        #     return 1231212
        # def __len__(self):
        #     return 10
    a = Person('alex')
    b = Person('egon')
    # print(len(a))
    # print(hash(a))
    print(a)
    print(b)

    # 类中的内置方法 很多都和 内置函数相关

  • 相关阅读:
    Insus Meta Utility
    The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
    Insus Binary Utility
    asp.net实现文件下载功能
    Column 'Column Name' does not belong to table Table
    程序已被编译为DLL,怎样去修改程序功能
    如何在Web网站实现搜索功能
    如何把数据流转换为二进制字符串
    Asp.net更新文件夹的文件
    如何显示中文月份
  • 原文地址:https://www.cnblogs.com/wangph/p/9069037.html
Copyright © 2011-2022 走看看