面对整体分为两个部分:
静态变量部分
方法部分
class A: company_name = '百度' # 静态变量(静态字段) __iphone = '1353333xxxx' # 私有静态变量(私有静态字段) def __init__(self,name,age): #普通方法(构造方法) self.name = name #对象属性(普通字段) self.__age = age # 私有对象属性(私有普通字段) def func1(self): # 普通方法 pass def __func(self): #私有方法 print(666) @classmethod # 类方法 def class_func(cls): """ 定义类方法,至少有一个cls参数 """ print('类方法') @staticmethod #静态方法 def static_func(): """ 定义静态方法 ,无默认参数""" print('静态方法') @property # 属性 def prop(self): pass
一,面向对象的私有
私有的
--名字
静态属性(静态字段)
动态属性(方法)
类方法
静态方法
特性
私有的特点
只能在类的内部被调用
不能被继承
什么时候用私有?
当不想被外部调用也不想被继承,只想在类的内部使用的时候
当在外部使用的时候,想给用户的使用前\后直接加上某些功能
私有+property使用
二,面相对象的特殊成员及相关内置函数
isinstance与issubclass
isinstance(obj,cls)检查obj是否是类 cls 的对象
class A: pass
class B(A): pass
abj = B()
print(isinstance(abj,B)) #True
print(isinstance(abj,A)) #True
issubclass(sub, super)检查sub类是否是 super 类的派生类
class A: pass class B(A): pass abj = B() print(issubclass(B,A)) #True
反射:
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩
什么是反射:用字符串类型的变量名来访问这个变量的值
反射的方法:hasattr getattr setattr delattr (前两个比较重要)
用到的地方 : 类 ,对象,模块,反射自己的模块
类:
反射查看属性
getattr(命名空间,‘变量名’) 第一个参数的命名空间中的变量名为第二个参数的变量,并得到它的值
反射调用方法
if hasattr(命名空间,’方法名‘): #查看方法是否存在
getattr(命名空间,‘方法名’) () # 可以是类方法 ,静态方法,普通方法
hasattr 和 getattr 如影相随
对象: 方法,对象属性
getattr(对象,’方法名‘)()
模块
getattr(模块,’指令‘)
例:
import os
getattr(os,'rename')('原文件名’,‘新文件名’)
反射自己的模块
import sys # 是一个模块,这个模块里的所有方法都是和python解释器相关
# sys.modules 是一个字典,记录所有在当前这个python程序中导入的模块
my_file=sys.modules['__main__'] # 找到当前的命名空间
getattr(my_mile,'方法名‘)()
__名字__
类中特殊方法\内置方法
双下方法\魔术方法 (外文翻译过来的叫法)
__call__ 相当于对象()
class A: def __call__(self, *args, **kwargs): print('哈哈哈') a=A() a() #对象加括号就可以调用call 方法 A()()
__len__ 相当于len(obj)
class A: def __init__(self,lis): self.lis=lis def __len__(self): return len(self.lis) obj=A([1,2,3,4,5]) print(len(obj))
__new__ 特别重要 开辟内存空间的 类的构造方法
class A: __num=None def __new__(cls,*args,**kwargs): if not cls.__num: cls.__num=object.__new__(cls) return cls.__num def __init__(self): pass a1=A() a2=A() print(a1) #打印的都是同一个对象空间 print(a2)
__str__ 相当于 str(obj), '%s' % obj print(obj)
print一个对象相当于调用一个对象的__str__方法
str(obj),相当于执行obj.__str__方法 ,
'%s'%obj,相当于执行obj.__str__方法
要求这个方法的返回值必须是字符串str类型
class Student: def __str__(self): return '%s %s %s'%(self.school,self.cls,self.name) def __init__(self,name,stu_cls): self.school = '北大' self.name = name self.cls = stu_cls he = Student('hezewei','py14') # print(he) huang = Student('huangdongyang','py14') # print(huang) # print(str(he)) # 内置的数据类型,内置的类,相当于执行__str__ print('学生1 : %s'%he)
__repr__
repr() , '%r ' %
是__str__的备胎.如果有__str__方法,那么 print ,%s, str 都先去执行__str__方法,并且使用__str__的返回值
如果没有__str__,那么 print %s str都会执行repr
repr(obj) , %r 不能用__str__ 代替,只能执行__repr__
在子类中使用__str__,先找子类的__str__,没有的话要向上找,只要父类不是object,就执行父类的__str__
但是如果除了object之外的父类都没有__str__方法,就执行子类的__repr__方法,如果子类也没有,
还要向上继续找父类中的__repr__方法.
一直找不到 再执行object类中的__str__方法
# class A: # def __init__(self,name): # self.name = name # def __str__(self): # return '**%s**'%self.name # def __repr__(self): # return self.name # # class B(A): # def __repr__(self): # return '***' # a = B('alex') # print(a) # print(str(a),repr(a)) # print('%s | %r'%(a,a)) # print('---%r---'%('abc')) # print('---%s---'%('abc'))
__del__ 析构方法 : 释放一个空间之前执行
某对象借用了操作系统的资源,还要通过析构方法归还回去 : 文件资源 网络资源
# 垃圾回收机制 # class A: # def __del__(self): # # 析构方法 del A的对象 会自动触发这个方法 # print('执行我了') # a = A() # del a # 对象的删除 del # print(a) # class File(): # # 处理文件的 # def __init__(self,file_path): # self.f = open(file_path) # self.name = 'alex' # # def read(self): # self.f.read(1024) # # def __del__(self): # 是去归还/释放一些在创建对象的时候借用的一些资源 # # del 对象的时候 程序员触发 # # python解释器的垃圾回收机制 回收这个对象所占得内存的时候 python自动触发的 # self.f.close() # f = File('文件名') # f.read() # 不管是主动还是被动,这个f对象总会被清理掉,被清理掉就触发__del__方法, 触发这个方法就会归还操作系统的文件资源
item 系列 和对象使用[]访问值有联系 __getitem__,__setitem__ ,__delitem__
在内置的模块中,
有一些特殊的方法,要求对象必须实现__getitem__/__setitem__才能使用
class A: def __getitem__(self, item): return getattr(self,item) def __setitem__(self, key, value): return setattr(self,key,value) def __delitem__(self, key): return delattr(self,key) a=A() a['key']=111 #触发的是__setitem__ print(a['key']) #触发的是__getitem__ del a['key'] #触发的是__delitem__ print(a['key']) # 用对象操作列表 class A: def __init__(self,lis): self.lis=lis def __getitem__(self, item): return self.lis[item] def __setitem__(self, key, value): self.lis[key]=value def __delitem__(self, key): self.lis.pop(key) lis=[1,2,3,4,5,6,7] a=A(lis) a[1]='你好啊' print(a.lis) del a[2] print(a.lis) print(a[0])
__hash__
hash方法
底层数据结构基于hash值寻址的优化操作
hash是一个算法
能够把某一个要存在内存的值通过一系列计算,保证不同的值的hash结构不一样
对同一个值在多次执行python代码的时候hash值是不同
但是对同一个值在同一次执行python代码的时候hash值永远不变
# print(hash('abc'))
# print(hash('abc'))
# print(hash('abc')) 一次执行的时候hash值不变
__eq__
==这个语法 是完全和__eq__相关
class A: def __init__(self,name,age): self.name = name self.age = age def __eq__(self, other): if self.name == other.name and self.age == other.age: return True a = A('alex',83) aa = A('alex',83) aa2 = A('alex',83) aa3 = A('alex',83) aa4 = A('alex',83) print(aa3 == aa == aa4)
# 一个类 # 对象的属性 : 姓名 性别 年龄 部门 # 员工管理系统 # 内部转岗 python开发 - go开发 # 姓名 性别 年龄 新的部门 # alex None 83 python # alex None 85 luffy # 1000个员工 # 如果几个员工对象的姓名和性别相同,这是一个人 # 请对这1000个员工做去重 class Employee: def __init__(self,name,age,sex,partment): self.name = name self.age = age self.sex = sex self.partment = partment def __hash__(self): return hash('%s%s'%(self.name,self.sex)) def __eq__(self, other): if self.name == other.name and self.sex == other.sex: return True employ_lst = [] for i in range(200): employ_lst.append(Employee('alex',i,'male','python')) for i in range(200): employ_lst.append(Employee('wusir',i,'male','python')) for i in range(200): employ_lst.append(Employee('taibai', i, 'male', 'python')) # print(employ_lst) employ_set = set(employ_lst) for person in employ_set: print(person.__dict__) # set集合的去重机制 : 先调用hash,再调用eq,eq不是每次都触发,只有hash值相等的时候才会触发
浙公网安备 33010602011771号