函数VS方法
从分类的角度来分析。
(1)函数的分类:
内置函数:python内嵌的一些函数。
匿名函数:一行代码实现一个函数功能。
递归函数
自定义函数:根据自己的需求,来进行定义函数。
(2)方法的分类:
普通方法:直接用self调用的方法。
私有方法:__函数名,只能在类中被调用的方法。
属性方法:@property,将方法伪装成为属性,让代码看起来更合理。
特殊方法(双下划线方法):以__init__为例,是用来封装实例化对象的属性,只要是实例化对象就一定会执行__init方法,如果对象子类中没有则会寻找父类(超类),如果父类(超类)也没有,则直接继承object(python 3.x)类,执行类中的__init__方法。
类方法:通过类名的调用去操作公共模板中的属性和方法。
静态方法:不用传入类空间、对象的方法, 作用是保证代码的一致性,规范性,可以完全独立类外的一个方法,但是为了代码的一致性统一的放到某个模块(py文件)中。
从作用域的角度来分析:
(1)函数作用域:从函数调用开始至函数执行完成,返回给调用者后,在执行过程中开辟的空间会自动释放,也就是说函数执行完成后,函数体内部通过赋值等方式修改变量的值不会保留,会随着返回给调用者后,开辟的空间会自动释放。
(2)方法作用域:通过实例化的对象进行方法的调用,调用后开辟的空间不会释放,也就是说调用方法中对变量的修改值会一直保留。
调用的方式不同。
(1)函数:通过“函数名()”的方式进行调用。
(2)方法:通过“对象.方法名”的方式进行调用。
class Foo(object):
def func(self):
pass
判断函数与方法的方式
print()
(1)print(func) # *<function func at 0x00000000005D1EA0>
(2)obj = Foo()
print(obj.func) # <bound method A.func of <main.A object at 0x0000000001DE1CF8>>
types模块
from types import FunctionType
from types import MethodType
def func():
pass
class A:
def func(self):
pass
@staticmethod
def f():
pass
# print(isinstance(func, FunctionType))
# print(isinstance(func, MethodType))
# 类名调用func 就是一个函数
# print(isinstance(A.func, FunctionType))
# print(isinstance(A.func, MethodType))
# obj = A()
# 对象调用func 就是一个方法
# print(isinstance(obj.func, FunctionType))
# print(isinstance(obj.func, MethodType))
# 对于静态方法的研究
# print(isinstance(A.f, FunctionType))
# print(isinstance(A.f, MethodType))
# obj = A()
# # 对象调用func
# print(isinstance(obj.f, FunctionType))
# print(isinstance(obj.f, MethodType))
# 函数与方法
# 函数: 全都是显性传参
# 方法: 存在隐性传参
反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。
python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
从实例的角度研究反射(4个反射函数)
class Foo:
static_field = '静态属性'
def __init__(self, name, age):
self.name = name
self.age = age
def func(self):
print('in A func')
obj=Foo('egon',73)
#检测是否含有某属性
print(hasattr(obj,'name'))
print(hasattr(obj,'say_hi'))
#获取属性
n=getattr(obj,'name')
print(n)
func=getattr(obj,'say_hi')
func()
print(getattr(obj,'aaaaaaaa','不存在啊')) #报错
#设置属性
setattr(obj,'sb',True)
setattr(obj,'show_name',lambda self:self.name+'sb')
print(obj.__dict__)
print(obj.show_name(obj))
#删除属性
delattr(obj,'age')
delattr(obj,'show_name')
delattr(obj,'show_name111')#不存在,则报错
print(obj.__dict__)
从类的角度研究反射
class Foo(object):
staticField = "old boy"
def __init__(self):
self.name = 'wupeiqi'
def func(self):
return 'func'
@staticmethod
def bar():
return 'bar'
print getattr(Foo, 'staticField')
print getattr(Foo, 'func')
print getattr(Foo, 'bar')
当前模块的反射
import sys
def s1():
print 's1'
def s2():
print 's2'
this_module = sys.modules[__name__]
hasattr(this_module, 's1')
getattr(this_module, 's2')
其他模块的反射
#一个模块中的代码
def test():
print('from the test')
"""
程序目录:
module_test.py
index.py
当前文件:
index.py
"""
# 另一个模块中的代码
import module_test as obj
#obj.test()
print(hasattr(obj,'test'))
getattr(obj,'test')()
反射的作用
学反射前:
class User:
def login(self):
print('欢迎来到登录页面')
def register(self):
print('欢迎来到注册页面')
def save(self):
print('欢迎来到存储页面')
while 1:
choose = input('>>>').strip()
if choose == 'login':
obj = User()
obj.login()
elif choose == 'register':
obj = User()
obj.register()
elif choose == 'save':
obj = User()
obj.save()
学反射后
class User:
def login(self):
print('欢迎来到登录页面')
def register(self):
print('欢迎来到注册页面')
def save(self):
print('欢迎来到存储页面')
user = User()
while 1:
choose = input('>>>').strip()
if hasattr(user,choose):
func = getattr(user,choose)
func()
else:
print('输入错误。。。。')