社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

在python中实现的虚拟函数没有任何初始化

Vinay Varahabhotla • 3 年前 • 1350 次点击  

考虑下面的代码:

class parent_print():
    
    def print_word(self):
        self.print_hello()
        
class child_print(parent_print):
    
    def print_hello(self):
        print('Hello')
        
        
basic_print = child_print()
basic_print.print_word()

这里我假设 打印你好 是父类中的虚拟函数。父对象(parent_print)的所有子对象都将实现一个名为 打印你好 .这样所有的孩子都可以调用一个函数 打印单词 并根据子对象的方法实现对print_hello函数进行适当的绑定。

但是在C++语言中,我们需要特别指出,函数在父类中是虚拟的。 事实上的 关键字,并使用函数析构函数符号~。

但是,在python中,如果不在python父类中提到函数,这怎么可能呢 打印你好 是一个虚拟的功能。

我假设python使用的概念是虚拟函数,如果我错了,请纠正我并解释这个概念。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/128454
 
1350 次点击  
文章 [ 1 ]  |  最新文章 3 年前
Samwise
Reply   •   1 楼
Samwise    3 年前

与其将其视为“虚拟函数”,不如将其视为“duck类型”的一个示例。在这个表达中:

self.print_hello()

我们只需访问 print_hello 属性 self (不管是什么),然后叫它。如果没有这样的属性,则 AttributeError 在运行时引发。如果属性不可调用,则 TypeError 她长大了。这就是全部。没有对这类问题做出任何假设 自己 --我们只是让它“像鸭子一样呱呱叫”,看看它能不能。

duck类型的危险在于,如果你实例化一个 parent_print 打电话 print_word 在这方面,它将失败:

abstract_print = parent_print()
abstract_print.print_word()
# raises AttributeError: 'parent_print' object has no attribute 'print_hello'

Python确实支持静态类型声明和抽象类的概念,这可以帮助您避免错误。例如,如果我们运行静态类型检查器( mypy )在您的代码中,我们将得到一个错误:

test.py:4: error: "parent_print" has no attribute "print_hello"

这是完全正确的——从静态类型的角度来看,调用 打印你好 因为我们还没有确定这一切 家长打印 实例具有这样的属性。

为了解决这个问题,我们可以宣布 打印你好 作为一种抽象方法(为了培养良好习惯,我还将清理名称以匹配标准Python约定):

from abc import ABC, abstractmethod

class ParentPrint(ABC):
    
    @abstractmethod
    def print_hello(self) -> None: ...

    def print_word(self) -> None:
        self.print_hello()
        
class ChildPrint(ParentPrint):
    
    def print_hello(self) -> None:
        print('Hello')
        
        
basic_print = ChildPrint()
basic_print.print_word()

现在代码类型检查没有问题。

这个 @abstractmethod decorator还指出该类是抽象的(“纯虚拟的”),无法实例化。如果我们试图创造一个 ParentPrint 任何 它的子类没有提供抽象方法的实现,我们得到一个错误, 二者都 静态地从 麦皮 在运行时以 打字错误 在您尝试实例化对象时(甚至在您尝试调用抽象方法之前),会立即引发该问题:

abstract_print = ParentPrint()
# raises error: Cannot instantiate abstract class "ParentPrint" with abstract attribute "print_hello"