面向对象进阶

成员

      类,对象=》静态字段,静态方法,普通字段,普通方法

      通过类访问有:静态字段,静态方法

      通过对象访问:普通字段,普通方法

成员修饰符

面向对象中一些常用特殊方法  __init__     __call__     __delitem__

反射查找类的成员

 1 #-*- coding:utf-8 -*-
 2 class abc(object):
 3    def __init__(self,name):
 4        self.name=name
 5    def a1(self):
 6        pass
 7 
 8 
 9 
10 f1=abc.__dict__
11 #查看类中方法
12 #print(f1)
13 
14 #反射:找类中的方法,__init__和a1
15 print(hasattr(abc,'a1'))
16 
17 #反射:对象,既可以找对象还可以找类中的方法
18 f1=abc('zhangs')
19 print(hasattr(f1,'name'))
20 print(hasattr(f1,'a1'))

反射:

反射导入模块,在找类然后初始化对象,最后根据对象知道对应的方法

 1 #-*- coding:utf-8 -*-
 2 
 3 #导入模块
 4 f1=__import__('f2',fromlist=True)
 5 
 6 #获取f1的类
 7 class_name=getattr(f1,'F1')
 8 
 9 #创建对象
10 obj=class_name("zhangs")
11 
12 #获取对象中的方法
13 result=getattr(obj,'name')
14 print(result)
15 
16 
17 结果:
18 zhangs
反射模块

类静态字段

 1 #-*- coding:utf-8 -*-
 2 
 3 class F1(object):
#类静态字段
4 country = '中国' 5 def __init__(self,name): 6 #对象方法 7 self.name=name 8 #self.country="中国" 这样写的缺点就是浪费内存,每一个对象都会有这个这个属性 9 def fun(self): 10 pass 11 12 a1=F1("黑龙江") 13 a2=F1("湖北") 14 a3=F1("湖南")

其实带self定义的就是对象方法,每生成一个对象都会有这个方法

类静态方法staticmethod

 1 class F1(object):
 2 
 3     def __init__(self):
 4         pass
 5     #静态方法必须加这个装饰器
 6     @staticmethod
 7     def static_func(x):
 8         print(x)
 9 
10 a1=F1()
11 #通过对象访问类的静态方法,原则上尽量不使用。要想使用也是用类的方法去访问
12 a1.static_func(1)
13 #通过类访问静态方法
14 F1.static_func(12)
静态方法

静态方法和函数差不多,直接调用。不愿意写函数的就是用这个方法。这个方法在c#或java 中就可以实现函数的方式

类方法classmethod

 1 #-*- coding:utf-8 -*-
 2 
 3 class F1(object):
 4 
 5     def __init__(self):
 6         pass
 7     #静态方法必须加这个装饰器
 8     @staticmethod
 9     def static_func(x):
10         print(x)
11 
12     #类方法会自动加一个类名,必须定义cls
13     @classmethod
14     def classfunc(cls):
15         print(cls)
16 
17 F1.classfunc()
18 
19 结果:
20 <class '__main__.F1'>
类方法

类方法比静态方法多一个功能就是传递一个类名

特性property

 1 #-*- coding:utf-8 -*-
 2 
 3 class F1(object):
 4    #普通方法
 5    def s1(self):
 6        print("s1")
 7 
 8    @property
 9    def s2(self):
10        print("s2")
11 
12 obj1=F1()
13 #执行普通方法
14 obj1.s1()
15 #执行特性方法,特性方法不需要写(),但是也无法加参数
16 obj1.s2
property

将方法伪造成字段

给property赋值方法,property中还是很少用到的知道就好了

 1 #-*- coding:utf-8 -*-
 2 
 3 class F1(object):
 4    @property
 5    def s2(self):
 6        print("s2")
 7    #给特性方法赋值就必须这么写,下面的方法名必须和上面一样
 8    @s2.setter
 9    def s2(self,value):
10        print(value)
11 obj1=F1()
12 #执行特性方法
13 obj1.s2
14 #给特性方法赋值
15 obj1.s2=123
16 
17 
18 结果:
19 s2
20 123
View Code

成员修饰符(公开或私有)

 1 class F1(object):
 2    abc=123
 3    __aaa=4565
 4    def __init__(self):
 5        self.__name="zhangs"
 6    #类的内部可以正常访问私有修饰符成员
 7    def s2(self):
 8        print(F1.__aaa)
 9        print(self.__name)
10 
11 
12 obj1=F1()
13 #静态方法或普通方法都不能直接访问私有修饰符成员
14 #obj1.__aaa
15 #obj1.__name  私有修饰符的普通方法也无法访问
16 
17 
18 #可以访问类公共修饰符变量
19 print(obj1.abc)
20 
21 #内部可以正常访问私有修饰符方法
22 print(obj1.s2())

私有对象修饰符和派生类测试

 1 #-*- coding:utf-8 -*-
 2 
 3 class F1(object):
 4    abc=123
 5    __aaa=4565
 6    def __init__(self):
 7        self.__name="zhangs"
 8    def __test(self):
 9        print("test")
10    def demo(self):
11        #内部可以调用私有修饰符成员对象
12        print self.__test()
13 
14 class F2(F1):
15     def abc(self):
16         print(self.__name)
17 
18 f2=F2()
19 #私有修饰符对象方法也不能直接调用,派生类也无法调用
20 # f2.abc()
21 # f2.__test()
22 f2.demo()
View Code

访问私有方法,知道就可以基本没人这么用

class f:

     __name=12

f1=f()

f1_f__name

__call__方法

 1 class f1:
 2     def __init__(self):
 3         print("__init__")
 4 
 5     def __call__(self, *args, **kwargs):
 6         print("__call__")
 7         return 1
 8 
 9 #很特殊的call方法调用
10 f=f1()()
11 
12 #上面的方法就是下面方法的简写,在看源码的时候要注意就这样写的
13 #实际上是调用的call方法
14 #f=f1()
15 #f()
16 
17 print(f)
18 
19 结果:
20 __init__
21 __call__
22 1
__call__

类成员魔法参数  __getitem__    __setitem__     __delitem__

 1 #-*- coding:utf-8 -*-
 2 class f1:
 3     def __init__(self):
 4         self.dick={}
 5     def __getitem__(self, item):
 6          if type(item) == dict:
 7             if self.dick.has_key(item):print(self.dick[item])
 8             else:print("{}")
 9          else:
10             print(item)
11 
12     def __setitem__(self, key, value):
13         self.dick[key]=value
14         print(key,value)
15 
16     def __delitem__(self, key):
17            del  self.dick[key]
18            print(key)
19 
20     def __delslice__(self, i, j):
21         print("__delslice__")
22 
23     def __setslice__(self, i, j, sequence):
24         print("__setslice__")
25 
26 
27 
28 f=f1()
29 #查找
30 f['aa']
31 
32 #设置
33 f['key']="value"
34 
35 #删除
36 del f['key']
37 
38 #切片
39 f[1:2]
40 
41 #设置切片
42 f[1:2]=[3,6]
43 
44 #删除切片
45 del f[1:2]
46 
47 
48 结果:
49 aa
50 ('key', 'value')
51 key
52 slice(1, 2, None)
53 __setslice__
54 __delslice__
View Code

__iter__为什么for可以循环某些对象?

 1 #-*- coding:utf-8 -*-
 2 class f1:
 3      #对象中包含这个方法就是说明这个对象可以被迭代了
 4      def __iter__(self):
 5          yield 1
 6          yield 2
 7          yield 3
 8 
 9 
10 
11 f=f1()
12 #循环可迭代的对象
13 for i in f:
14     print(i)
原文地址:https://www.cnblogs.com/menkeyi/p/6768523.html