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)

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

  • 相关阅读:
    找出有序数组中绝对值最小的数
    warning:deprecated conversion from string constant to 'char *' 解决方案
    Wordnet 与 Hownet 比较
    心灵鸡汤
    冒泡排序
    .NET加密配置文件connectionStrings节点
    C#基础知识之方法重载总结
    [C#]工具类—FTP上传下载
    C#基础知识-对象初始化顺序
    自定义Dictionary支持线程安全
  • 原文地址:https://www.cnblogs.com/wangph/p/9069037.html
Copyright © 2011-2022 走看看