Python面向对象知识汇总
1.类与对象
对象=属性(特征)+方法(行为) 类:在python中,把具有相同属性和方法的对象归为一个类(class)
2.属性查找
先找对象自己,找不到去类中找,再找不到就在类的__mro__列表中查找(Python2 和Python3 一个是深度优先一个是广度优先)
3.类属性和对象属性
类属性指的是类对象所绑定的属性,在类加载的时候,就已被分配了内存只有一份,所有new出来的对象都共享此属性。 而对象的属性属于单个实例化的对象,每new一个实例就在堆内存中创建一份,就等于多个拷贝,占内存多,但比较灵活,自己修改自己的属性值,互不影响。
4.对象的绑定方法
1.绑定到对象的方法的特殊之处在于,绑定给谁就由谁来调用,谁来调用,就会将‘谁’本身当做第一个参数传给方法,即self 2.类也可以来调用绑定方法,但是类调用就是普通函数,有几个参数就要传几个参数
5.函数和方法
1、函数要手动传self,方法不用传self。 2、如果是一个函数,用类名去调用,如果是一个方法,用对象去调用。
6.类的继承(python支持多继承)
1.python允许在一个或多个类的基础上生成新的类,新的类可以使用父类的一些属性和方法,这个过程就叫做继承。 2.python继承最大的作用就是为了减少代码。
7.派生
派生就是子类在继承父类的基础上衍生出新的属性。子类中独有的,父类中没有的;或子类定义与父类重名的东西。子类也叫派生类。
8.super()特殊的对象
super()避免了基类的显式调用
9.多继承下的super(FatBossGril.mro)
多继承上,super方法能保证每个父类的方法只会执行一次
10.组合
属性的值是指向另外一个类的对象
11.多态与多态性
1.多态指的是一类事物有多种形态 2.多态性:一种调用方式,不同的执行效果
12.封装
实际python中的封装只是一个约定 第一层面的封装:类就好像一个袋子,这就是一种封装 第二层面的封装:类中定义私有的,只有类内部使用,通过_或__隐藏对象的属性和实现细节,仅对外提供公共访问方式。
13.property
加了@property后,可以用调用属性的形式来调用方法,后面不需要加()
14.类方法
1、对象方法:通常第一个参数self,由类实例化后的对象调用,会将对象自动传入到self 2、类方法:使用@classmethod,第一个参数是cls,是对当前类做的额外的处理,类方法需要用类去调用,而不是实例对象调用,会将类自动传入到cls 3、静态方法:使用@staticmethod装饰器,默认没有参数
15.isinstance与type
isinstance() 会认为子类是一种父类类型,考虑继承关系。 type() 不会认为子类是一种父类类型,不考虑继承关系。
16.反射getattr,setattr,hasattr,delattr
1 hasattr:判断一个对象里面是否有特定属性或者方法,返回BOOL值,有特性返回True, 否则返回False。需要注意的是属性或者方法是字符串要用引号括起来。 2.getattr:获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选。需要注意的是,如果是返回的对象的方法,返回的是方法的内存地址,如果需要运行这个方法,可以在后面添加一对括号。 3.setattr:给对象的属性赋值,若属性不存在,先创建再赋值。 4.delattr:删除对应的属性
17
18.init和new__
1.__new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例对象,是个静态方法。 2.__init__是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值,通常用在初始化一个类实例的时候。是一个实例方法。
也就是: __new__先被调用,__init__后被调用,__new__的返回值(实例)将传递给__init__方法的第一个参数,然后__init__给这个实例设置一些参数。
19.元类
元类就是Python在背后用来创建所有类的类。一个类没有声明自己的元类,默认他的元类就是type,除了使用内置元类type,我们也可以通过继承type来自定义元类,然后使用metaclass关键字参数为一个类指定元类
20.元类和object的区别
1.type:所有类的类,但是继承object 2.object:所有类的父类,同时由type生成
21.__setitem__、__getitem__、__delitem__
__setitem__:每当属性被赋值/更新的时候都会调用该方法,因此不能再该方法内赋值 self.name = value 会死循环 __getitem__:在使用点调用且属性不存在时会调用该方法 __delitem__:当删除属性时调用该方法
1)__getitem__
#访问不存在的属性时会调用该方法
class Zoo:
def __getitem__(self, name):
print("xxxxxxxxxxx")
return 6666
zoo = Zoo()
x = zoo["name"]
print(x)
----------------------------------------------------------------------------
结果:
xxxxxxxxxxx
6666
2)__setitem__
#每当属性被赋值的时候都会调用该方法 ,因此不能再该方法内赋值 self.name = value 会死循环
class Zoo:
def __setitem__(self, key,value):
print("%s 是 %s"%( key,value))
print(self.__dict__)
zoo = Zoo()
zoo["ALEX"] = 'SB' #注意结果不会放到__dict__中
----------------------------------------------------------------------------
结果:
ALEX 是 SB
{}
3)__delitem__
#删除属性时调用该方法
class Zoo:
def __delitem__(self, key):
print("谁特么让你删 %s 的" % key)
zoo = Zoo()
del zoo["alex"]
----------------------------------------------------------------------------
结果:
谁特么让你删 alex 的
4).示例,使用__setattr__ 和 __getattr__ 实现类属性的赋值类型限制,只允许整形
class Foo:
def __getattr__(self, item): print(item) return 99 def __setattr__(self, key, value): if isinstance(value,int):
'''错误的方法
1.使用反射 setattr(self,key,value) # setattr本质还是调用了self.key=value,会发生死循环
2.使用self.赋值 self.age = value # 与上类似,也会发生死循环
''' # 可以使用的方式
# 1.利用__dict__赋值 # self.__dict__[key] = value # 这种方式解决递归问题
# 2.利用其他类__setattr__方法 # 普通函数,有几个参数,就传几个参数 object.__setattr__(self,key,value) else: raise Exception('不让放') def printsize(self): print(self.__size) f = Foo() print(f.__dict__) # f.age = '19' # 放的age必须是数字 # f.age = 19 # 放的age必须是数字 # print(f.age) # # # object.__setattr__(f,'_Foo__size',178) #把属性直接设置为私有属性 # # print(f.size) # f.printsize() # print(f._Foo__size) # print(f.xxx) # print(f.xx)
不使用字典实现 中括号[ ] 赋值
class Foo:
def __setitem__(self, key, value):
setattr(self, key, value)
# object.__setattr__(self,key,value)
def __getitem__(self, item):
return getattr(self, item)
f = Foo()
f.name = 'lqz'
print(f.name)
print(f['name'])
f['age'] = 19
print(f.age)
print(f['age'])
22.单例模式实现三个方法:
1)类方法实现单例模式
import settings
class Mysql:
__instance=None
def __init__(self,host,port):
self.host=host
self.port=port
@classmethod
def singleton(cls):
if not cls.__instance:
cls.__instance=cls(settings.HOST,settings.PORT)
return cls.__instance
obj1=Mysql('1.1.1.2',3306)
obj2=Mysql('1.1.1.3',3307)
print(obj1 is obj2) #False
obj3=Mysql.singleton()
obj4=Mysql.singleton()
print(obj3 is obj4) #True
2)定制元类实现单例模式
import settings
class Mymeta(type):
def __init__(self,name,bases,dic): #定义类Mysql时就触发
# 事先先从配置文件中取配置来造一个Mysql的实例出来
self.__instance = object.__new__(self) # 产生对象
self.__init__(self.__instance, settings.HOST, settings.PORT) # 初始化对象
def __call__(self, *args, **kwargs): #Mysql(...)时触发
if args or kwargs: # args或kwargs内有值
obj=object.__new__(self)
self.__init__(obj,*args,**kwargs)
return obj
return self.__instance
class Mysql(metaclass=Mymeta):
def __init__(self,host,port):
self.host=host
self.port=port
obj1=Mysql() # 没有传值则默认从配置文件中读配置来实例化,所有的实例应该指向一个内存地址
obj2=Mysql()
obj3=Mysql()
print(obj1 is obj2 is obj3)
obj4=Mysql('1.1.1.4',3307)
3)装饰器实现单例模式
import settings
def singleton(cls): #cls=Mysql
_instance=cls(settings.HOST,settings.PORT)
def wrapper(*args,**kwargs):
if args or kwargs:
obj=cls(*args,**kwargs)
return obj
return _instance
return wrapper
@singleton # Mysql=singleton(Mysql)
class Mysql:
def __init__(self,host,port):
self.host=host
self.port=port
obj1=Mysql()
obj2=Mysql()
obj3=Mysql()
print(obj1 is obj2 is obj3) #True
obj4=Mysql('1.1.1.3',3307)
obj5=Mysql('1.1.1.4',3308)
print(obj3 is obj4) #False
"一劳永逸" 的话,有是有的,而 "一劳永逸" 的事却极少

浙公网安备 33010602011771号