1、面向对象
1、面向对象的结构
class A: company_name = '' # 静态变量(静态字段) __iphone = '' # 私有静态变量(私有静态字段) def __init__(self,name,age): #特殊方法 self.name = name #对象属性(普通字段) self.__age = age # 私有对象属性(私有普通字段) def func1(self): # 普通方法 pass def __func(self): #私有方法 print("哈哈") @classmethod # 类方法 def class_func(cls): """ 定义类方法,至少有一个cls参数 """ print('类方法') @staticmethod #静态方法 def static_func(): """ 定义静态方法 ,无默认参数""" print('静态方法') @property # 属性 def prop(self): pass
2、面向对象的私有与公有
#对于每一个类的成员而言都有两种形式: # 公有成员,在任何地方都能访问, # 私有成员,只有在类的内部才能方法 #私有成员和公有成员的访问限制不同: #静态字段(静态变量) # 公有静态字段:类可以访问;类内部可以访问;派生类中可以访问 # 私有静态字段:仅类内部可以访问; #总结: #对于这些私有成员来说,他们只能在类的内部使用,不能再类的外部以及派生类中使用. #ps:非要访问私有成员的话,可以通过 对象._类__属性名,但是绝对不允许!!! #为什么可以通过._类__私有成员名访问呢?因为类在创建时,如果遇到了私有成员(包括私有静态字段,私有普通字段,私有方法)它会将其保存在内存时自动在前面加上_类名.
2、方法
方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。
class Student: def __init__(self,name,age): self.__name = name #对象的私有方法 self.__age = age #普通的实例方法 def play(self): print(self.__name+"来玩啊") #类方法,在不需要对象参与的方法中,可以使用类方法 @classmethod def high(cls): print("你身高多高?") #静态方法,该方法和对象和类都没有关系,就是一个普通的函数 @staticmethod def wahahaha(): print("谁都管不着我")
3、属性
1、property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值
2、将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则
3、由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除
class Foo: @property def HAHA(self): print('get的时候运行我啊') @HAHA.setter def HAHA(self,value): print('set的时候运行我啊') @HAHA.deleter def HAHA(self): print('delete的时候运行我啊') #只有在属性HAHA定义property后才能定义HAHA.setter,HAHA.deleter f1=Foo() f1.HAHA f1.HAHA='aaa' del f1.HAHA 或者: class Foo: def get_HAHA(self): print('get的时候运行我啊') def set_HAHA(self,value): print('set的时候运行我啊') def delete_HAHA(self): print('delete的时候运行我啊') HAHA=property(get_HAHA,set_HAHA,delete_HAHA) #内置property三个参数与get,set,delete一一对应 f1=Foo() f1.HAHA f1.HAHA='aaa' del f1.HAHA
4、面相对象的特殊成员及相关内置函数
1、isinstance(obj,cls)检查是否obj是否是类 cls 的对象
class A: pass class B(A): pass abj = B() print(isinstance(abj,B)) #True print(isinstance(abj,A)) #True #isinstance检查abj是否是B的时候,会考虑继承关系 #type(abj,B)和isinstance用法相同,当时不会考虑继承关系
2、issubclass(sub, super)检查sub类是否是 super 类的派生类
class A: pass class B(A): pass abj = B() print(issubclass(B,A)) #True
3、enumerate函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列
语法:enumerate(sequence, [start=0]) #sequence -- 一个序列、迭代器或其他支持迭代对象。 #start -- 下标起始位置。 seasons = ['Spring', 'Summer', 'Fall', 'Winter'] list(enumerate(seasons)) [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')] i = 0 seq = ['one', 'two', 'three'] for element in seq: ... print i, seq[i] ... i +=1 ... #结果:0 one #1 two #2 three
5、反射
1、python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
class Foo: f = '类的静态变量' def __init__(self,name,age): self.name=name self.age=age def say_hi(self): print('hi,%s'%self.name) obj=Foo('egon',73) #检测是否含有某属性 print(hasattr(obj,'name')) print(hasattr(obj,'say_hi')) #获取属性 n=getattr(obj,'name') print(n) func=getattr(obj,'say_hi') func() print(getattr(obj,'aaaaaaaa','不存在啊')) #报错 #设置属性 setattr(obj,'sb',True) setattr(obj,'show_name',lambda self:self.name+'sb') print(obj.__dict__) print(obj.show_name(obj)) #删除属性 delattr(obj,'age') delattr(obj,'show_name') delattr(obj,'show_name111')#不存在,则报错 print(obj.__dict__)
6、内置方法(魔术方法)
1、__call__(self, *args, **kwargs)
对象后面加括号,触发执行。注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
class Foo: def __init__(self): pass def __call__(self, *args, **kwargs): print('__call__') obj = Foo() # 执行 __init__ obj() # 执行 __call__
2、__len__(self):长度方法
len(对象)函数,执行实际调用的是对象内的__len__函数,如果该对象没有__len__方法,则会报差错
class A: def __init__(self): self.a = 1 self.b = 2 def __len__(self): return len(self.__dict__) a = A() print(len(a))
3、__init__(self):初始化方法
#初始化方法 #1、首先开辟一块内存空间 #2、把对象空间传给self,执行init #3、把这个对象的空间返回给该对象
4、__new__(cls, *args, **kwargs):构造方法
4.1、__new__方法在实例化之后,__init__之前调用
#__new__方法在实例化之后,__init__之前调用 class A: def __init__(self): self.x = 1 print('in init function') def __new__(cls, *args, **kwargs): print('in new function') return object.__new__(A) a = A() print(a.x)
4.2、单例模式
#单例模式 class A: __ISINSTANCE = None def __new__(cls,*args,**kwargs): if not cls.__ISINSTANCE: cls.__ISINSTANCE = object.__new__(cls) return cls.__ISINSTANCE def __init__(self,name,age): self.name = name self.age = age a = A("张三",20) b = A("李四",25) print(a.name) print(b.name) print(a,b)
5、__str__(self)
class A: def __init__(self): pass def __str__(self): return '太白' a = A() print(a) print('%s' % a) #print方法相当于调用__str__ #str()相当于调用__str__ #'%s'%obj相当于调用__str__
6、__repr__(self)
class A: def __init__(self): pass def __repr__(self): return 'haha' a = A() print(repr(a)) print('%r'%a)
7、__del__(self)
析构方法,当对象在内存中被释放时,自动触发执行。
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
8、item系列
class Foo: def __init__(self,name): self.name=name def __getitem__(self, item): print(self.__dict__[item]) def __setitem__(self, key, value): self.__dict__[key]=value def __delitem__(self, key): print('del obj[key]时,我执行') self.__dict__.pop(key) def __delattr__(self, item): print('del obj.key时,我执行') self.__dict__.pop(item) f1=Foo('sb') f1['age']=18 f1['age1']=19 del f1.age1 del f1['age'] f1['name']='alex' print(f1.__dict__)
9、hash(self)
class A: def __init__(self): self.a = 1 self.b = 2 def __hash__(self): return hash(str(self.a)+str(self.b)) a = A() print(hash(a))