了解RPA:
www.i-search.com.cn

“ 私有函数,魔法函数,回调函数”

在任何编程语言中,都会规定某些对象 (属性、方法、函数、类等) 只能够在某个范围内访问,出了这个范围就不能访问了。这是“公”、“私”之分。此外,还会专门为某些特殊的东西指定一些特殊表示,比如类的名字就不能用 class,def 等,这就是保留字。除了保留字,python 中还为类的名字做了某些特殊准备,就是“专有”的范畴。

01

私有函数

有时在项目中会看到这样一些函数。

图片

图片

在某些时候,会看到有一种方法命名比较特别,是以“__”双划线开头的,将这类命名的函数 / 方法称之为“私有函数”。

所谓私有函数,不可以从它们的模块外面被调用;私有类方法不能够从它们的类外面被调用;私有属性不能够从它们的类外面被访问。跟私有对应的,就是所谓的公有啦。有的编程语言用特殊的关键词来说明某函数或方法或类是私有还是公有。但是 python 仅仅用名字来说明,因为 python 深刻理解了两千年前孔子所说的“名不正言不顺”的含义。

如果一个 python 函数, 类方法, 或属性的名字以两个下划线开始 (但不是结束), 它是私有的; 其它所有的都是公有的。类方法或者是私有 (只能在它们自已的类中使用) 或者是公有 (任何地方都可使用)。

例如:

class Person:
def init(self, name):
 self.name = name
 print(self.name)def __work(self, salary):
 print("%s salary is: %d" % (self.name, salary))
 if name == “main”:
 officer = Person(“Tom”)
 officer.__work(1000)

运行结果:

Tom
 Traceback (most recent call last):
 File “C:/Users/Administrator/PycharmProjects/Myworld/work.py”, line 13, in
 officer.__work(1000)
 AttributeError: ‘Person’ object has no attribute ‘__work’

从运行结果中可以看出,当运行到 officer.__work(1000) 的时候,报错了。并且从报错信息中说,没有该方法。这说明,这个私有方法,无法在类外面调用(其实类外面可以调用私有方法,就是太麻烦,况且也不提倡)。

将上述代码进行如下修改:

class Person:
 def init(self, name):
 self.name = name
 print(self.name)def __work(self, salary):
 print("%s salary is: %d" % (self.name, salary))def worker(self):
 self.__work(500) # 在类内部调用私有方法
 if name == “main”:
 officer = Person(“Tom”) # Tom

officer.__work(1000)

officer.worker() # Tom salary is: 500

得到正确结果

02

魔法函数

有时在项目中会看到这样一些函数。

图片

如果是以双划线开头,但不是以它结尾,所命名的方法是私有方法;

如果以双划线开头,并且以双划线结尾,所命名的方法就是专有方法。也叫魔法函数。

比如内置函数 init(), 就是一个典型的专有方法。关于专有方法,除了 init() 之外,还有诸如:str,setitem 等等,要想看,可以利用 dir() 函数在交互模式下看看某个函数里面的专有方法。

例如:

python code to demonstrate example of
 dir() number
 class std_info:
 name = “Amit shukla”
 age = 21
 course = “B.Tech (CS)”printing return type of dir() function
 print(“return type of dir():”, type(dir(std_info)))printing details using dir() function
 print(dir(std_info))

查看结果:

return type of dir(): <class ‘list’>
 [‘class’, ‘delattr’, ‘dict’, ‘dir’, ‘doc’,
 ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘gt’,
 ‘hash’, ‘init’, ‘le’, ‘lt’, ‘module’, ‘ne’,
 ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘se
 tattr’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘weakref’,
 ‘age’, ‘course’, ‘name’]

魔法函数:init()

所有类的超类 object,有一个默认包含 pass 的 __ init __() 实现,这个函数会在对象初始化的时候调用,我们可以选择实现,也可以选择不实现,一般建议是实现的,不实现对象属性就不会被初始化,虽然我们仍然可以对其进行赋值,但是它已经成了隐式的了,编程时显示远比隐式的更好。

看下面的小栗子:

class test_1:
 def method(self):
 self.a = “1”
 self.b = “2”
 return self.a,self.bclass test_2:
 def init(self):
 self.a = “1”
 self.b = “2”def method(self):
 return self.a,self.bprint(vars(test_1()))
 print(“-”*10)
 print(vars(test_2()))
 “”"
 {}
 {‘a’: ‘1’, ‘b’: ‘2’}
 “”"

我们可以通过 vars 函数获知显示声明的属性,但是隐式的就无法获知了,这并不值得提倡,但是在知道参数的情况下我们还是可以对其进行赋值的,如下:

class test_1:
 def method(self):
 return self.a, self.bclass test_2:
 def init(self):
 self.a = “1”
 self.b = “2”def method(self):
 return self.a, self.bt1 = test_1()
 t1.a = 1
 t1.b = 2
 print(t1.method()) # (1, 2)
 print(‘-’ * 10)
 t2 = test_2()
 t2.a = 3
 t2.b = 4
 print(t2.method()) # (3, 4)03

回调函数

回调函数就是一个通过函数名调用的函数。如果你把函数的名字(地址)作为参数传递给另一个函数,当这个参数被用来调用其所指向的函数时,我们就说这是回调函数.

回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应.

上面是对回调函数的描述和解释, 概念往往都显得生涩拗口, 不易理解.

简单来说, 我们可以这样理解回调,A 实现了 A1 函数和 A3 函数,B 实现了 B2 函数,B2 函数接收一个函数名字作为参数, 然后在 B2 内执行这个函数.

在实际应用时,A1 函数调用了 B2,B2 函数接收函数 A3 作为参数, 在 B2 内部执行 A3 函数,A3 就是回调函数.