诚意
诚意如你,当一诚的态度对待

导航

 

1     和面向对象相关的常用内置函数

1.1   issubclass

作用:

检查第一个参数是否是第二个参数的 子子孙孙类

案例:

 1 class Base(object):
 2     pass
 3 
 4 class Foo(Base):
 5     pass
 6 
 7 class Bar(Foo):
 8     pass
 9 # 检查第一个参数是否是第二个参数的 子子孙孙类
10 print(issubclass(Bar,Base)) #True

 

1.2   type

作用:

获取当前对象是由那个类创建

实例:

 1 class Foo(object):
 2     pass
 3 
 4 obj = Foo()
 5 
 6 print(obj,type(obj)) # 获取当前对象是由那个类创建。
 7 if type(obj) == Foo:
 8     print('obj是Foo类型')
 9 
10 答案:
11 # <__main__.Foo object at 0x0000014F613E83C8> <class '__main__.Foo'>
12 # obj是Foo类型
13 
14  

 

 1 class Foo(object):
 2     pass
 3 
 4 class Bar(object):
 5     pass
 6 
 7 def func(*args):
 8     foo_counter =0
 9     bar_counter =0
10     for item in args:
11         if type(item) == Foo:
12             foo_counter += 1
13         elif type(item) == Bar:
14             bar_counter += 1
15     return foo_counter,bar_counter
16 
17 # result = func(Foo(),Bar(),Foo())
18 # print(result)
19 v1,v2 = func(Foo(),Bar(),Foo())
20 print(v1,v2)    #2 1
View Code

 

1.3   isinstance

作用:

检查第一个参数(对象)是否是第二个参数(类及父类)的实例

案例:

 1 class Base(object):
 2     pass
 3 
 4 class Foo(Base):
 5     pass
 6 
 7 obj1 = Foo()
 8 print(isinstance(obj1,Foo))  # 检查第一个参数(对象)是否是第二个参数(类及父类)的实例。    #True
 9 print(isinstance(obj1,Base)) # 检查第一个参数(对象)是否是第二个参数(类及父类)的实例。    #True
10 
11 obj2 = Base()
12 print(isinstance(obj2,Foo))  # 检查第一个参数(对象)是否是第二个参数(类及父类)的实例。   #False
13 print(isinstance(obj2,Base)) # 检查第一个参数(对象)是否是第二个参数(类及父类)的实例。    #True
View Code

 

 

1.4   type与isinstance的区别

给你一个参数,判断对象是不是由某一个指定类? type                  --> type(obj) == Foo

给你一个参数,判断对象是不是由某一个指定类或其父类? isinstance    --> instance(obj,Foo)

 

形象一点:

type:只认她岳父岳母(具体)

isinstance:认她岳父岳母以及她的所有长辈

 

2     方法和函数的区别

2.1   介绍

称谓:

       类,方法

       外,函数

到底方法函数?

       对象.xxx  --> xxx就是方法

       类.xxx    --> xxx就是函数

       xxx       --> xxx就是函数

打印查看:

       function

       method

 

 

实例

 1 class Foo(object):
 2 
 3     def detail(self):
 4         pass
 5 
 6     @staticmethod
 7     def ss():
 8         pass
 9 def func():
10     pass
11 
12 obj = Foo()
13 print(obj.detail)  #<bound method Foo.detail of <__main__.Foo object at 0x000001BBBAC38470>>
14 print(Foo.ss)   #<function Foo.ss at 0x000001BBBAC39A60>
15 print(func)     #<function func at 0x00000145E2659950>
View Code

 

2.2   最科学的区分函数和方法

 1 from types import MethodType,FunctionType
 2 def check(arg):
 3     '''
 4     检查arg是方法还是函数?
 5     :param arg:
 6     :return:
 7     '''
 8     if isinstance(arg,MethodType):
 9         print('这是一个方法')
10     elif isinstance(arg,FunctionType):
11         print('这是一个函数')
12     else:
13         print('不知道是什么')
14 
15 def func():
16     pass
17 
18 class Foo(object):
19     def detail(self):
20         pass
21     @staticmethod
22     def xxx():
23         pass
24 
25 
26 check(func)   #这是一个函数
27 
28 obj = Foo()
29 check(obj.detail)       #这是一个方法
30 check(obj.xxx)          #这是一个函数
View Code

 

2.3   特点(与调用者有关系,调用的方式不同,就不同)

 1 class Foo(object):
 2 
 3     def f1(self):
 4         pass
 5 
 6     def f2(self):
 7         pass
 8 
 9     def f3(self):
10         pass
11 
12 
13 obj = Foo()
14 print(Foo.f1) # 把f1当做函数,类的调用方式不能直接传参 #<function Foo.f1 at 0x00000159EFB698C8>
15 
16 obj = Foo()
17 print(obj.f1)    # 把f1当做方法,自动传self值  #<bound method Foo.f1 of <__main__.Foo object at 0x00000159EFB689E8>>
18 总结:类.    是函数
19     对象.   是方法
View Code

 

3     如何判断一个参数一个类还是对象呢?

1 #判断一个对象是不是类
2 class Foo:
3     pass
4 
5 print(type(Foo)==type)    #True    #返回True表示是类
6 
7  
View Code

 

4      callable() 如何判断一个对象是否能被调用呢?

4.1   什么可以被调用?

- 类()

- 对象()

- 函数()

- 方法()

4.2   callable() 那么如何判断一个对象是否能被调用?

 1 # callable()判断一个对象是否可以被调用
 2 def func():
 3    pass
 4 
 5 class Foo(object):
 6     def __call__(self, *args, **kwargs):
 7         pass
 8     def func(self):
 9         pass
10 obj = Foo()
11 
12 
13 print(callable(func))   #True
14 print(callable(Foo))    #True
15 print(callable(obj))    #True
16 print(callable(obj.func))   #True
View Code

 

 

5     为什么要有方法与函数的划分呢

下面是个人的浅见:

方法可以自动传参,这就是区别,但是这只不过是省了一个步骤而已,为何要多此一举的在区分函数和方法呢?在这里你应该把这个self参数当作一个封装的包裹,里面的东西不仅仅是一个东西,这样的话,就有必要区分函数和方法

 

6     反射

所谓反射,就是一种映射关系。

下面我们由一种需求来引出反射的必要性

 

 

v = getattr(obj,"func")  # 根据字符串为参数(第二个参数),去对象(第一个参数)中寻找与之同名的成员

6.1   需求

6.1.1 之前的方式

 1 while True:
 2     print("""
 3     系统支持的函数有:
 4         1. f1
 5         2. f2
 6         3. f3
 7         4. f4
 8         5. f5
 9     """)
10     val = int(input("请输入要执行的函数:"))
11     
12     if val == 1:
13         pass
14     elif val == 2:
15         pass
16     elif val == 3:
17         pass
18     elif val == 4:
19         pass
20     elif val == 5:
21         pass
View Code

如上面的方式,我们需要用到if ... elif ... elif ... else ... 。但这种方式对于判断大量数据的时候就有些不好了,下面看反射的方式

 

6.1.2 反射的方式(在模块中的应用)

 1 ##handler.py 
 2 
 3 f0 = 9
 4 
 5  
 6 
 7 def f1():
 8 
 9     print('F1')
10 
11  
12 
13 def f2():
14 
15     print('F2')
16 
17  
18 
19 def f3():
20 
21     print('F3')
22 
23  
24 
25 def f4():
26 
27     print('F4')
28 
29  
30 
31 def f5():
32 
33     print('F5')
View Code

 

 

 1 from types import FunctionType
 2 import handler
 3 
 4 while True:
 5     print("""
 6     系统支持的函数有:
 7         1. f1
 8         2. f2
 9         3. f3
10         4. f4
11         5. f5
12     """)
13     val = input("请输入要执行的函数:")  # val = "f1"
14     # 错误
15     # handler.val()       #用这种方式代替if ...elif....elif...else,但尝试失败。因为val本质是一个字符串并不是一个内存地址
16 
17     if hasattr(handler, val):  # 判断handler模块是否有val变量的内容所代表的函数
18         func_or_val = getattr(handler, val)  # 根据字符串为参数,去handler模块中寻找与之同名的成员。
19         if isinstance(func_or_val, FunctionType):
20             func_or_val()  # 如果是方法就执行这个方法,否则打印
21         else:
22             print(func_or_val)
23     else:
24         print('handler中不存在输入的属性名')
25 
26  
27 
28 注意:从上面可以看是怎么体现反射的,所谓反射就是映射关系。通过getattr来判断映射项中是否有与之对应的。
View Code

 

案例1:在面向对象中的应用

 1 class Foo(object):
 2 
 3     country = "中国"
 4 
 5     def func(self):
 6         pass
 7 
 8 
 9 v = getattr(Foo,'func') # Foo.func # 根据字符串为参数,去类中寻找与之同名的成员。
10 print(v)            #<function Foo.func at 0x00000153C64198C8>
11 
12 obj = Foo()
13 v = getattr(obj,"func") # obj.func # 根据字符串为参数,去对象中寻找与之同名的成员。
14 print(v)                #<bound method Foo.func of <__main__.Foo object at 0x00000153C64184E0>>
View Code

案例2:

 1 class Foo(object):
 2     
 3     def __init__(self,a1):
 4         self.a1 = a1
 5         self.a2 = None
 6 
 7 obj = Foo(1)
 8 
 9 v1 = getattr(obj,'a1')
10 print(v1)           #1
11 
12 setattr(obj,'a2',2) #更改变量
13 
14 v2 = getattr(obj,'a2')
15 print(v2)           #2
View Code

案例3:

 1 class Account(object):
 2 
 3     func_list = ['login', 'logout', 'register']
 4 
 5  
 6 
 7     def login(self):
 8 
 9         """
10 
11         登录
12 
13         :return:
14 
15         """
16 
17         print('登录111')
18 
19  
20 
21     def logout(self):
22 
23         """
24 
25         注销
26 
27         :return:
28 
29         """
30 
31         print('注销111')
32 
33  
34 
35     def register(self):
36 
37         """
38 
39         注册
40 
41         :return:
42 
43         """
44 
45         print('注册111')
46 
47  
48 
49     def run(self):
50 
51         """
52 
53         主代码
54 
55         :return:
56 
57         """
58 
59         print("""
60 
61             请输入要执行的功能:
62 
63                 1. 登录
64 
65                 2. 注销
66 
67                 3. 注册
68 
69         """)
70 
71  
72 
73         choice = int(input('请输入要执行的序号:'))
74 
75         func_name = Account.func_list[choice-1]
76 
77  
78 
79         # func = getattr(Account,func_name) # Account.login
80 
81         # func(self)
82 
83  
84 
85         func = getattr(self, func_name)  # self.login
86 
87         func()
88 
89  
90 
91 obj1 = Account()
92 
93 obj1.run()
94 
95  
96 
97 obj2 = Account()
98 
99 obj2.run()
View Code
posted on 2018-08-30 21:37  诚意  阅读(231)  评论(0)    收藏  举报