什么是动态调度和鸭子类型?
What is dynamic dispatch and duck typing?
在使用Pycharm时,经常会指出错误,说:
Unresolved reference 'name'. This inspection detects names that should
resolve but don't. Due to dynamic dispatch and duck typing, this is
possible in a limited but useful number of cases. Top-level and
class-level items are supported better than instance items.
我已经对此有所了解,但我发现的大多数问题和信息都是关于防止消息显示的。我想知道的是:
- 什么是动态 dispatch/duck 键入?
- 这些 "useful number of cases" 是什么(或例子)?
Python 使用鸭子打字约定。这意味着您不必指定名称的类型。例如,与 Java 不同,您必须明确指定该变量的类型可以是 int
或 Object
。本质上,类型检查是在运行时完成的。
"If it walks like a duck and it quacks like a duck, then it must be a duck."
在 Python 中,一切似乎都正常,直到您使用尝试以非设计的方式操纵对象。基本上,一个对象可能没有另一个对象可能具有的特定方法或属性,并且直到 Python 在尝试它时抛出错误,您才会发现这一点。
Dynamic Dispatch 是编译器或环境选择在运行时使用哪个版本的多态函数的做法。如果你有一个方法的多个实现,你可以以不同的方式使用它们,尽管这些方法具有相同或相似 properties/attributes。这是一个例子:
class Foo:
def flush():
pass
class Bar:
def flush():
pass
两者 类 都有一个 flush()
方法,但在运行时选择了正确的名称。
Python 不是此过程的最佳示例,因为方法可以采用多个参数并且不必重新实现。 Java 是一个更好的例子,但我不够流利,无法提供正确的例子。
警告意味着您正在使用 PyCharm 无法识别的变量,但由于 Python 的动态特性,无法确定它是否正确或您'没错。
例如你可能有以下代码:
class myClass():
def myfunc(self):
print(self.name)
PyCharm大概会抱怨self.name
无法解决。但是,您可以像这样使用 class:
my_class = myClass()
my_class.name = "Alastair"
my_class.myfunc()
这是完全有效的(尽管很脆弱)。
消息继续说它对不那么模糊的属性和方法更有信心。例如:
class myClass():
my_instance_var = "Al"
def myfunc(self):
print(self.my_instance_var)
由于 my_instance_var
在源代码中定义(class 属性),PyCharm 可以确信它存在。
(除非您知道自己在做什么,否则不要使用 class 属性!)
在使用Pycharm时,经常会指出错误,说:
Unresolved reference 'name'. This inspection detects names that should resolve but don't. Due to dynamic dispatch and duck typing, this is possible in a limited but useful number of cases. Top-level and class-level items are supported better than instance items.
我已经对此有所了解,但我发现的大多数问题和信息都是关于防止消息显示的。我想知道的是:
- 什么是动态 dispatch/duck 键入?
- 这些 "useful number of cases" 是什么(或例子)?
Python 使用鸭子打字约定。这意味着您不必指定名称的类型。例如,与 Java 不同,您必须明确指定该变量的类型可以是 int
或 Object
。本质上,类型检查是在运行时完成的。
"If it walks like a duck and it quacks like a duck, then it must be a duck."
在 Python 中,一切似乎都正常,直到您使用尝试以非设计的方式操纵对象。基本上,一个对象可能没有另一个对象可能具有的特定方法或属性,并且直到 Python 在尝试它时抛出错误,您才会发现这一点。
Dynamic Dispatch 是编译器或环境选择在运行时使用哪个版本的多态函数的做法。如果你有一个方法的多个实现,你可以以不同的方式使用它们,尽管这些方法具有相同或相似 properties/attributes。这是一个例子:
class Foo:
def flush():
pass
class Bar:
def flush():
pass
两者 类 都有一个 flush()
方法,但在运行时选择了正确的名称。
Python 不是此过程的最佳示例,因为方法可以采用多个参数并且不必重新实现。 Java 是一个更好的例子,但我不够流利,无法提供正确的例子。
警告意味着您正在使用 PyCharm 无法识别的变量,但由于 Python 的动态特性,无法确定它是否正确或您'没错。
例如你可能有以下代码:
class myClass():
def myfunc(self):
print(self.name)
PyCharm大概会抱怨self.name
无法解决。但是,您可以像这样使用 class:
my_class = myClass()
my_class.name = "Alastair"
my_class.myfunc()
这是完全有效的(尽管很脆弱)。
消息继续说它对不那么模糊的属性和方法更有信心。例如:
class myClass():
my_instance_var = "Al"
def myfunc(self):
print(self.my_instance_var)
由于 my_instance_var
在源代码中定义(class 属性),PyCharm 可以确信它存在。
(除非您知道自己在做什么,否则不要使用 class 属性!)