PYTHON开发--面向对象基础二

一、成员修饰符
    共有成员
    私有成员, __字段名
    - 无法直接访问,只能间接访问

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
View Code

也可以通过下面的这种方法

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)
View Code 

这和最上面的第一个程序差不多,就是通过普通方法来实现

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     ,这是老师延伸的,具体的我也不是太清楚,那么  面向对象这一块差不多就到这里了,以上都是我对其的简单认识,有什么不足的地方请多多指教。

原文地址:https://www.cnblogs.com/mars527/p/5913770.html