Python基础-面向对象进阶
Posted 鸿飞漫天
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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‘)
导入模块,反射模块中的名字
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)
# 类中的内置方法 很多都和 内置函数相关
以上是关于Python基础-面向对象进阶的主要内容,如果未能解决你的问题,请参考以下文章
Python基础-第七天-面向对象编程进阶和Socket编程简介