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