首页 > 解决方案 > 为什么python中的变量确实在变量名称前面使用()的语法之类的函数,但它们实际上不是函数?

问题描述

  1. 在python中可以定义多少种变量?

  2. 有没有什么方法可以通过像符号这样的函数调用另一个变量?

例如:

 from tensorflow.keras import layers

 inputs = keras.Input(shape=(784,))


 dense = layers.Dense(64, activation='relu')

 x = dense(inputs)

我的问题很密集是一个变量,它像函数一样将输入作为参数。

TensorFlow 中的 Keras 函数式 API

标签: pythontensorflowkeras

解决方案


A variable may have different types such as int and function in runtime, which can be inspected with the type() built-in function.

Also variable can be used with () like a function when its reference is callable, which can be tested using the callable() built-in function.

Furthermore, in Python a function can return another function and a class instance can be made callable, like a function.

Here is an example to illustrate, first we define 3 simple functions:

def sum(a, b):
    return a + b

def mul(a, b):
    return a * b

def noop(a, b):
    pass

Then we define a function that takes one argument and returns another function:

def chooseOperation(sign):
    operations = {"+": sum, "*": mul} # sum and mul are functions
    return operations[sign] if sign in operations else noop # noop is a function

Finally, we declare a variable that receives the result of a function call, which is a reference to one of those simple functions.

operation = chooseOperation("+") # returns sum
print(operation(2, 3)) # 5

operation = chooseOperation("*") # returns mul
print(operation(2, 3)) # 6

operation = chooseOperation("%") # returns noop
print(operation(2, 3)) # None 

You can inspect a variable type with type(variable):

print(type(operation)) # <class 'function'>

Therefore, if a variable is of type <class 'function'> it means you can call that function through this variable.

In the case of Dense from TensorFlow API, its type is as follows:

from tensorflow.keras import layers

dense = layers.Dense(64, activation='relu')

print(type(dense)) # <class 'tensorflow.python.keras.layers.core.Dense'>
print(callable(dense)) # True

The important part to understand is that the dense variable references an instance of the class Dense, which is callable. This is what allows you to use () with the dense variable.

The TensorFlow API source code may be a little too much to ingest, so consider this simple example:

class Dense():

    def sum(self, a, b):
        return a + b

    def __call__(self, a, b): # Instances will now be callable
        return self.sum(a, b)

dense = Dense() # Dense constructor, no args

print(type(dense)) # <class '__main__.Dense'>

sum = dense(1, 6) # 7 - Triggers __call__ which in turn calls sum(1, 6)

When a class implements __call__ its instances become callable, like a function.

The way it is implemented in TensorFlow API is a bit different due to the more complex inheritance structure but follows the same principle.


推荐阅读