一、成员修饰符
共有成员
私有成员, __字段名
- 无法直接访问,只能间接访问
1. 私有成员
1.1 普通方法种的私有成员
1 class Foo: 2 def __init__(self, name, age): 3 self.name = name 4 # self.age = age 5 self.__age = age #__age前面加上__就表示私有成员,不能直接访问,只能间接访问
2个下划线 __字段名 就表示私有成员了 6 obj = Foo("sang",20) 7 obj.name 8 # obj.age 9 obj.__age
结果:
AttributeError: 'Foo' object has no attribute '__age'
那么我么就可以通过show函数来间接访问,如下:
1 class Foo: 2 def __init__(self, name, age): 3 self.name = name 4 # self.age = age 5 self.__age = age 6 def show(self): 7 return self.__age 8 obj = Foo("sang",20) 9 obj.name 10 # obj.age 11 #obj.__age 12 ret = obj.show() 13 print(ret)
我们还可以通过静态方法来访问:
1 class Foo: 2 __v = '123' 3 def __init__(self): 4 pass 5 def show(self): 6 return Foo.__v 7 @staticmethod 8 def stat(): 9 return Foo.__v 10 # print(Foo.__v) 11 # ret = Foo().show() 12 # print(ret) 13 ret = Foo.stat() 14 print(ret) 15 16 结果为: 17 123
也可以通过下面的这种方法
1 class Foo: 2 def __f1(self): 3 return 123 4 def f2(self): 5 r = self.__f1() 6 return r 7 obj = Foo() 8 ret = obj.f2() 9 print(ret)
这和最上面的第一个程序差不多,就是通过普通方法来实现
1.2 类中的私有成员
1 class f: 2 def __init__(self): 3 self.ge = 123 4 self.__gene = 234 5 class s(f): 6 def __init__(self,name): 7 self.name = name 8 self.__age = 22 9 super(s,self).__init__() 10 def show(self): 11 print(self.name) 12 print(self.__age) 13 print(self.ge) 14 #print(self.__gene) # 私有成员只能是自己类中的,才能去访问
#AttributeError: 's' object has no attribute '_s__gene'
15 s = s("sang") 16 s.show()
二:特殊成员
1 __init__ 类()自动执行 2 __del__ 3 __call__ 对象() 类()() 自动执行 4 __int__ int(对象) 5 __str__ str() 6 7 __add__ 8 __dict__ # 讲对象中封装的所有内容通过字典的形式返回 9 __getitem__ # 切片(slice类型)或者索引 10 __setitem__ 11 __delitem__ 12 13 __iter__ 14 # 如果类中有 __iter__ 方法,对象=》可迭代对象 15 # 对象.__iter__() 的返回值: 迭代器 16 # for 循环,迭代器,next 17 # for 循环,可迭代对象,对象.__iter__(),迭代器,next 18 # 1、执行li对象的类F类中的 __iter__方法,并获取其返回值 19 # 2、循环上一步中返回的对象
2.1 类中自动执行
class foo: def __init__(self): print("init") def __call__(self, *args, **kwargs): print("call") # def __str__(self): # return sang obj = foo() obj() # obj()#foo()() 等价
2.2 int str 成员
1 class foo: 2 def __init__(self): 3 pass 4 def __int__(self): 5 return 111111 6 def __str__(self): 7 return "aang" 8 obj = foo() 9 print(obj,type(obj)) 10 #int,对象,自动执行对象的__int__方法,并将返回值赋值给对象, 11 #那么str对象其实是一样的 12 r = int(obj) 13 print(r) 14 j = str(obj) 15 print(j)
结果:
aang <class '__main__.foo'> 111111 aang
2.21
1 class Foo: 2 def __init__(self,n,a): 3 self.name =n 4 self.age =a 5 def __str__(self): 6 return '%s-%s' %(self.name,self.age,) 7 obj = Foo('alex', 18) 8 print(obj) #在内部已经调用print(str(obj)) str(obj) obj中__str__,并获取其返回值
2.3 __add__, __del__成员
1 class Foo: 2 def __init__(self, name,age): 3 self.name = name 4 self.age = age 5 def __add__(self, other): 6 # self = obj1 (alex,19) 7 # other = obj2(eric,66) 8 #return self.age + other.age 9 #return Foo('tt',99) 10 return Foo(obj1.name, other.age) 11 # def __del__(self): 12 # print('析构方法') # 对象被销毁()时,自动执行 13 obj1 = Foo("alex", 19) 14 obj2 = Foo('eirc', 66) 15 r = obj1 + obj2 16 # 两个对象相加时,自动执行第一个对象的的 __add__方法,并且将第二个对象当作参数传递进入 17 print(r,type(r))
2.4 __dict__ # 讲对象中封装的所有内容通过字典的形式返回
1 class Foo: 2 # def __init__(self, name,age): 3 # self.name = name 4 # self.age = age 5 # self.n = 123 6 # 7 # obj = Foo('alex', 18) 8 # d = obj.__dict__ 9 # print(d) 10 # 11 # ret = Foo.__dict__ 12 # print(ret)
2.5 具体效果看代码演示
__getitem__ # 切片(slice类型)或者索引 __setitem__ __delitem_
1 class Foo: 2 def __init__(self, name,age): 3 self.name = name 4 self.age = age 5 6 def __getitem__(self, item): 7 return item+10 8 9 def __setitem__(self, key, value): 10 print(key,value) 11 12 def __delitem__(self, key): 13 print(key) 14 li = Foo('alex', 18) 15 r= li[8] # 自动执行li对象的类中的 __getitem__方法,8当作参数传递给item 16 print(r) 17 18 li[100] = "asdf" 19 20 del li[999]
切片:
1 class Foo: 2 def __init__(self, name,age): 3 self.name = name 4 self.age = age 5 def __getitem__(self, item): 6 #return item+10 7 # 如果item是基本类型:int,str,索引获取 8 # slice对象的话,切片 9 if type(item) == slice: 10 print('调用这希望内部做切片处理') 11 else: 12 print(item.start) 13 print(item.stop) 14 print(item.step) 15 print('调用这希望内部做索引处理') 16 17 def __setitem__(self, key, value): 18 print(key,value) 19 def __delitem__(self, key): 20 print(key) 21 22 li = Foo('alex', 18) 23 li[123] 24 #li[1:4:2] 25 26 # li[1:3] = [11,22] 27 # 28 # del li[1:3]
2.6 iter
1 class Foo: 2 def __init__(self, name,age): 3 self.name = name 4 self.age = age 5 def __iter__(self): 6 return iter([11,22,33]) 7 li = Foo('alex', 18) 8 # 如果类中有 __iter__ 方法,对象=》可迭代对象 9 # 对象.__iter__() 的返回值: 迭代器 10 # for 循环,迭代器,next 11 # for 循环,可迭代对象,对象.__iter__(),迭代器,next 12 # 1、执行li对象的类F类中的 __iter__方法,并获取其返回值 13 # 2、循环上一步中返回的对象 14 for i in li: 15 print(i) 16 17 li = [11,22,33,44] 18 li= list([11,22,33,44]) 19 for item in li: 20 print(item)
三: 对象
metaclass,类的祖宗 a. Python中一切事物都是对象 b. class Foo: pass obj = Foo() # obj是对象,Foo类 # Foo类也是一个对象,type的对象 c. 类都是type类的对象 type(..) “对象”都是以类的对象 类()
1 class MyType(type): 2 def __init__(self,*args, **kwargs): 3 # self=Foo 4 print(123) 5 pass 6 def __call__(self, *args, **kwargs): 7 print("you are good") 8 # self=Foo 9 #r = self.__new__() 10 class foo(object,metaclass=MyType): 11 def __init__(self): 12 pass 13 def func(self): 14 print("helo world") 15 obj = foo()
四:异常处理
1 while True: 2 try: 3 # 代码块,逻辑 4 inp = input('请输入序号:') 5 i = int(inp) 6 except Exception as e: 7 # e是Exception对象,对象中封装了错误信息 8 # 上述代码块如果出错,自动执行当前块的内容 9 print(e) 10 i = 1 11 print(i)
做了一个小测试结果为:
请输入序号:666 666 请输入序号:qwe invalid literal for int() with base 10: 'qwe' 1 请输入序号:
这是一个简单的逻辑处理错误
4.1索引错误和值错误
1 # li = [11,22] 2 # li[999] # IndexError #他们是细分领域的错误 3 #int('qwe') # ValueError
4.1.1
1 try: 2 li = [11,22] 3 li[999] 4 int("asdf") 5 except IndexError as a: #索引错误,index和value只是一部分 6 print("IndexError",a) 7 except ValueError as a: 8 print("ValueError",a) 9 except Exception as a: #代表所有的错误类型 10 print("Exception",a) 11 else: 12 print("else") 13 finally: 14 print("fiasdasd")
结果为;
IndexError list index out of range
fiasdasd
4.1.2 主动触发异常
1 try: 2 # int('asdf') 3 # 主动触发异常 4 raise Exception('不过了...') 5 except Exception as e: 6 print(e)
主动触发异常 可以看下面这个例子,就省掉了一个地方的日志记录
1 def db(): 2 # return True 3 return False 4 5 def index(): 6 try: 7 r = input(">>") 8 int(r) 9 10 11 result = db() 12 if not result: 13 r = open('log','a') 14 r.write('数据库处理错误') 15 # 打开文件,写日志 16 #raise Exception('数据库处理错误') 在这里主动触发上面的日志记录就可以去掉了,
只需在下面记录一下就可以,省去一次
17 except Exception as e: 18 str_error = str(e) 19 print(str_error) 20 r = open('log', 'a') 21 r.write(str_error) 22 # 打开文件,写日志 23 24 index()
4.1.3 自定义异常的一个值
1 class OldBoyError(Exception): 2 def __init__(self, msg): 3 self.message = msg 4 def __str__(self): 5 return self.message 6 # obj = OldBoyError('xxx') 7 # print(obj) 8 try: 9 raise OldBoyError('我错了...') 10 except OldBoyError as e: 11 print(e)# e对象的__str__()方法,获取返回
4.14 断言,条件错误
# # assert 条件,断言,用于强制用户服从,不服从就报错,可 捕获,一般不捕获 # print(23) # assert 1 == 1#正确 # assert 2 == 3# 错误 # print(456)
五:反射
5.1通过字符串的形式去操作对象中的成员
1 class foo: 2 def __init__(self,name,age): 3 self.name = name 4 self.age = age 5 def show(self): 6 return "%s-%s"%(self.name,self.age) 7 obj = foo("alex",33) 8 9 getattr() 10 hasattr() 11 setattr() 12 delattr() 13 通过字符串的形式操作对象中的成员 14 15 16 func = getattr(obj,"show") 17 print(func) 18 r = func() 19 print(r) 20 21 print(hasattr(obj,"name")) 22 print(hasattr(obj,"name1")) 23 24 obj.k1 25 setattr(obj,"k1","v1") 26 print(obj.k1) 27 28 obj.name 29 delattr(obj,"name") 30 obj.name
# inp = input('>>>')
# v = getattr(obj, inp)
# print(v)
结果为:
<bound method foo.show of <__main__.foo object at 0x00000027579125C0>> Traceback (most recent call last): alex-33 True False v1 File "G:/Pycharm文件/week6/day5/day5私有.py", line 141, in <module> obj.name AttributeError: 'foo' object has no attribute 'name'
"""
obj.name
b = "name"
obj.b # obj.name
"""
# b = "name"
# obj.__dict__['name']
# obj.__dict__[b]
# if b == 'name':
# obj.name
5.11类也是一个对象,
""" class Foo: stat = '123' def __init__(self, name,age): self.name = name self.age = age # 通过字符串的形式操作对象中的成员 r = getattr(Foo, 'stat') print(r) """
5.2 我们也可以通过 当前的文件去访问另外一个文件里的内容打个比方 s1 和 s2,2个py目录
s1:
1 import s2 2 # r1 = s2.NAME 3 # print(r1) 4 # r2 = s2.func() 5 # print(r2) 6 7 r1 = getattr(s2, 'NAME') 8 print(r1) 9 10 r2 = getattr(s2, 'func') 11 result = r2() 12 print(result) 13 14 cls = getattr(s2, 'Foo') 15 print(cls) 16 obj = cls() 17 print(obj) 18 print(obj.name)
s2:
1 # NAME = 'alex' 2 # 3 # def func(): 4 # return 'qwe' 5 # 6 # class Foo: 7 # def __init__(self): 8 # self.name = 123
当然呢,我们也可以这样,
1 # import day3 2 # #while True: 3 # inp = input("请输入要查看的URL:") 4 # if hasattr(day3,inp): 5 # func = getattr(day3,inp) #我们就可以通过getattr直接调用day3里面的内容 6 # result = func() 7 # print(result) 8 # else: 9 # print("404")
day3里面的情况是这样的
1 def f1(): 2 return "首页" 3 4 def f2(): 5 return "新闻" 6 7 def f3(): 8 return "精华"
六: 单例模式
6.1 实例
1 class Foo: 2 def __init__(self, name,age): 3 self.name = name 4 self.age = age 5 6 obj = Foo() # obj对象,obj也成为Foo类的 实例,(实例化) 7 obj1 = Foo("aaa",12) 8 obj2 = Foo() 9 obj3 = Foo()
6.2 单例
1 # 单例,用于使用同一份实例(对象) 2 3 class Foo: 4 def __init__(self, name,age): 5 self.name = name 6 self.age = age 7 def show(self): 8 print(self.name,self.age) 9 v = None 10 while True:#for i in range(3): 11 if v: 12 v.show() 13 else: 14 v = Foo('alex', 123) 15 v.show()
6.21 如果我们想要使用单例的话,就不用类()了,直接通过里面的get方法去调用
1 # class foo: 2 # __v = None 3 # @classmethod 4 # def get_instance(cls): 5 # if cls.__v : 6 # return cls.__v 7 # else: 8 # cls.__v = foo() 9 # return cls.__v 10 # obj1 = foo.get_instance() 11 # print(obj1) 12 # obj2 = foo.get_instance() 13 # print(obj2) 14 # obj3 = foo.get_instance() 15 # print(obj3)
6.3 通过一个简单的网站去 查看信息
1 import tornado.ioloop 2 import tornado.web 3 class MainHandler(tornado.web.RequestHandler): 4 def get(self): 5 import time 6 self.write(str(time.time())) 7 application = tornado.web.Application([ 8 (r"/index", MainHandler), 9 ]) 10 11 if __name__ == "__main__": 12 application.listen(8888) 13 tornado.ioloop.IOLoop.instance().start()
这也是一个实例 的 例子,当然 这里我们需要先安装 一个pip3 install tornado ,这是老师延伸的,具体的我也不是太清楚,那么 面向对象这一块差不多就到这里了,以上都是我对其的简单认识,有什么不足的地方请多多指教。