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)

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

猜你喜欢

转载自www.cnblogs.com/wangph/p/9069037.html