我的编程空间,编程开发者的网络收藏夹
学习永远不晚

在Python中使用静态,类或抽象方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

在Python中使用静态,类或抽象方法

方法是存储在类属性中的函数,你可以用下面这种方式声明和访问一个函数

>>> class Pizza(object):
    ...     def __init__(self, size):
    ...         self.size = size
    ...     def get_size(self):
    ...         return self.size
    ...
    >>> Pizza.get_size
    <unbound method Pizza.get_size>

Python在这里说明了什么?Pizza类的属性get_size是unbound(未绑定的),这代表什么含义?我们调用一下就明白了:

 >>> Pizza.get_size()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unbound method get_size() must be called with Pizza instance as first argument (got nothing instead)

我们无法调用它(get_size),因为它没有绑定到Pizza的任何实例上,而且一个方法需要一个实例作为它的第一个参数(Python2中必须是类的实例,Python3没有这个强制要求),让我们试一下:

 >>> Pizza.get_size(Pizza(42))
    42

我们使用一个实例作为这个方法的第一个参数来调用它,没有出现任何问题。但是如果我说这不是一个方便的调用方法的方式,你将会同意我的观点。我们每次调用方法都要涉及(这里我理解是引用)类

来看Python打算为我们做些什么,就是它从Pizza类中绑定所有的方法到这个类的任何实例上。意思就是Pizza实例化后get_size这个属性是一个绑定方法,方法的第一个参数会是实例对象自己

>>> Pizza(42).get_size
    <bound method Pizza.get_size of <__main__.Pizza object at 0x7f3138827910>>
    >>> Pizza(42).get_size()
    42

意料之中,我们不需要为get_size传任何参数,自从被绑定后,它的self参数会自动设置为Pizza实例,下面是一个更明显的例子:

>>> m = Pizza(42).get_size
    >>> m()
    42

事实上是,你甚至不需要对Pizza引用,因为这个方法已经绑定到了这个对象

如果你想知道这个绑定方法绑定到了哪一个对象,这里有个快捷的方法:

 >>> m = Pizza(42).get_size
    >>> m.__self__
    <__main__.Pizza object at 0x7f3138827910>
    >>> # You could guess, look at this:
    ...
    >>> m == m.__self__.get_size
    True

明显可以看出,我们仍然保持对我们对象的引用,而且如果需要我们可以找到它

在Python3中,类中的函数不再被认为是未绑定的方法(应该是作为函数存在),如果需要,会作为一个函数绑定到对象上,所以原理是一样的(和Python2),只是模型被简化了

 >>> class Pizza(object):
    ...     def __init__(self, size):
    ...         self.size = size
    ...     def get_size(self):
    ...         return self.size
    ...
    >>> Pizza.get_size
    <function Pizza.get_size at 0x7f307f984dd0>

静态方法一种特殊方法,有时你想把代码归属到一个类中,但又不想和这个对象发生任何交互:

class Pizza(object):
        @staticmethod
        def mix_ingredients(x, y):
            return x + y

        def cook(self):
            return self.mix_ingredients(self.cheese, self.vegetables)

上面这个例子,mix_ingredients完全可以写成一个非静态方法,但是这样会将self作为第一个参数传入。在这个例子里,装饰器@staticmethod 会实现几个功能:

Python不会为Pizza的实例对象实例化一个绑定方法,绑定方法也是对象,会产生开销,静态方法可以避免这类情况

>>> Pizza().cook is Pizza().cook
        False
        >>> Pizza().mix_ingredients is Pizza.mix_ingredients
        True
        >>> Pizza().mix_ingredients is Pizza().mix_ingredients
        True

简化了代码的可读性,看到@staticmethod我们就会知道这个方法不会依赖这个对象的状态(一国两制,高度自治)
允许在子类中重写mix_ingredients方法。如果我们在顶级模型中定义了mix_ingredients函数,继承自Pizza的类除了重写,否则无法改变mix_ingredients的功能

什么是类方法,类方法是方法不会被绑定到一个对象,而是被绑定到一个类中

 >>> class Pizza(object):
    ...     radius = 42
    ...     @classmethod
    ...     def get_radius(cls):
    ...         return cls.radius
    ... 
    >>> 
    >>> Pizza.get_radius
    <bound method type.get_radius of <class '__main__.Pizza'>>
    >>> Pizza().get_radius
    <bound method type.get_radius of <class '__main__.Pizza'>>
    >>> Pizza.get_radius == Pizza().get_radius
    True
    >>> Pizza.get_radius()
    42

无论以何种方式访问这个方法,它都会被绑定到类中,它的第一个参数必须是类本身(记住类也是对象)

什么时候使用类方法,类方法在以下两种场合会有很好的效果:
1、工厂方法,为类创建实例,例如某种程度的预处理。如果我们使用@staticmethod代替,我们必须要在代码中硬编码Pizza(写死Pizza),这样从Pizza继承的类就不能使用了

 class Pizza(object):
            def __init__(self, ingredients):
                self.ingredients = ingredients

            @classmethod
            def from_fridge(cls, fridge):
                return cls(fridge.get_cheese() + fridge.get_vegetables())

2、使用静态方法调用静态方法,如果你需要将一个静态方法拆分为多个,可以使用类方法来避免硬编码类名。使用这种方法来声明我们的方法Pizza的名字永远不会被直接引用,而且继承和重写方法都很方便

class Pizza(object):
            def __init__(self, radius, height):
                self.radius = radius
                self.height = height

            @staticmethod
            def compute_area(radius):
                 return math.pi * (radius ** 2)

            @classmethod
            def compute_volume(cls, height, radius):
                 return height * cls.compute_area(radius)

            def get_volume(self):
                return self.compute_volume(self.height, self.radius)

抽象方法是定义在基类中的,可以是不提供任何功能代码的方法
在Python中简单的写抽象方法的方式是:

 class Pizza(object):
        def get_radius(self):
            raise NotImplementedError

继承自Pizza的类都必须要实现并重写get_redius,否则就会报错

这种方式的抽象方法有一个问题,如果你忘记实现了get_radius,只有在你调用这个方法的时候才会报错

  >>> Pizza()
    <__main__.Pizza object at 0x7fb747353d90>
    >>> Pizza().get_radius()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 3, in get_radius
    NotImplementedError

使用python的abc模块可以是这个异常被更早的触发

 import abc

    class BasePizza(object):
        __metaclass__  = abc.ABCMeta

        @abc.abstractmethod
        def get_radius(self):
             """Method that should do something."""

使用abc和它的特殊类,如果你尝试实例化BasePizza或者继承它,都会得到TypeError错误

>>> BasePizza()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: Can't instantiate abstract class BasePizza with abstract methods get_radius

备注:我使用Python3.6实现的代码

In [8]: import abc
       ...:
       ...: class BasePizza(abc.ABC):
       ...:
       ...:     @abc.abstractmethod
       ...:     def get_radius(self):
       ...:          """:return"""
       ...:

    In [9]: BasePizza()
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-9-70b53ea21e68> in <module>()
    ----> 1 BasePizza()

    TypeError: Can't instantiate abstract class BasePizza with abstract methods get_radius

如果对Python编程、网络爬虫、机器学习、数据挖掘、web开发、人工智能、面试经验交流。感兴趣可以519970686,群内会有不定期的发放免费的资料链接,这些资料都是从各个技术网站搜集、整理出来的,如果你有好的学习资料可以私聊发我,我会注明出处之后分享给大家。

当需要创建类和继承时,如果你需要混合这些方法装饰器,这里有一些小窍门建议给你
记住要将方法声明为抽象,不要冻结这个方法的原型。意思是它(声明的方法)必须要执行,但是它在执行的时候,参数不会有任何限制

 import abc

        class BasePizza(object):
            __metaclass__  = abc.ABCMeta

            @abc.abstractmethod
            def get_ingredients(self):
                 """Returns the ingredient list."""

        class Calzone(BasePizza):
            def get_ingredients(self, with_egg=False):
                egg = Egg() if with_egg else None
                return self.ingredients + egg

这样是有效的,因为Calzone实现了我们为BasePizza定义的接口要求,这意味着我们也可以将它实现为一个类或者静态方法,例如:

import abc

        class BasePizza(object):
            __metaclass__  = abc.ABCMeta

            @abc.abstractmethod
            def get_ingredients(self):
                 """Returns the ingredient list."""

        class DietPizza(BasePizza):
            @staticmethod
            def get_ingredients():
                return None

这也是正确的,它实现了抽要BasePizza的要求,事实上是get_ingredioents方法不需要知道对象返回的结果,
因此,你不需要强制抽象方法实现成为常规方法、类或者静态方法。在python3中,可以将@staticmethod和@classmethod装饰器放在@abstractmethod上面

 import abc

        class BasePizza(object):
            __metaclass__  = abc.ABCMeta

            ingredient = ['cheese']

            @classmethod
            @abc.abstractmethod
            def get_ingredients(cls):
                 """Returns the ingredient list."""
                 return cls.ingredients

和Java的接口相反,你可以在抽象方法中实现代码并通过super()调用它

  import abc

        class BasePizza(object):
            __metaclass__  = abc.ABCMeta

            default_ingredients = ['cheese']

            @classmethod
            @abc.abstractmethod
            def get_ingredients(cls):
                 """Returns the ingredient list."""
                 return cls.default_ingredients

        class DietPizza(BasePizza):
            def get_ingredients(self):
                return ['egg'] + super(DietPizza, self).get_ingredients()

在上面的例子中,继承BasePizza来创建的每个Pizza都必须重写get_ingredients 方法,但是可以使用super()来获取default_ingredients

出处 https://blog.csdn.net/Stephen...

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

在Python中使用静态,类或抽象方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

在Python中使用静态,类或抽象方法

方法是存储在类属性中的函数,你可以用下面这种方式声明和访问一个函数>>> class Pizza(object): ... def __init__(self, size): ... self.size
2023-01-31

关于如何在Python中使用静态、类或抽

方法是存储在类属性中的函数,你可以用下面这种方式声明和访问一个函数 >>> class Pizza(object): ... def __init__(self, size): ... self.s
2023-01-30

关于如何在Python中使用静态、类或

Python中方法的工作方式方法是存储在类属性中的函数,你可以用下面这种方式声明和访问一个函数>>> class Pizza(object): ... def __init__(self, size): ...
2023-01-31

在Python中定义和使用抽象类的方法

像java一样python也可以定义一个抽象类。 在讲抽象类之前,先说下抽象方法的实现。 抽象方法是基类中定义的方法,但却没有任何实现。在java中,可以把方法申明成一个接口。而在python中实现一个抽象方法的简单的方法是:class S
2022-06-04

python抽象类的使用方法

这篇文章主要介绍了python抽象类的使用方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、问题描述主要使用场景是这样的比如京东上买东西,买完东西后需要支付,京东可以使用
2023-06-08

静态方法与抽象方法在PHP中的差异解析

静态方法与抽象方法在PHP中的差异解析在PHP中,静态方法和抽象方法是面向对象编程中常用的概念,它们分别具有不同的特点和用法。本文将分别介绍静态方法和抽象方法的概念,然后通过具体的代码示例来说明它们之间的差异。静态方法是属于类的方法,可
静态方法与抽象方法在PHP中的差异解析
2024-03-05

在Python中定义和使用 抽象类及抽象

原文链接:http://www.jb51.net/article/87710.htm本文根据自己的理解和思考,对原文略有改动。。。Python中我们可以使用abc模块来构建抽象类。在讲抽象类之前,先说下抽象方法的实现。抽象方法是基类中定义的
2023-01-31

PHP中的静态方法与抽象方法详解

PHP作为一种常用的服务器端脚本语言,有许多高级特性可供开发者灵活运用。其中,静态方法和抽象方法在面向对象编程中起着重要的作用。本文将深入探讨PHP中静态方法和抽象方法的概念、用法和实际示例,帮助读者更好地理解和应用这两种方法。静态方法
PHP中的静态方法与抽象方法详解
2024-03-05

JAVA抽象类和抽象方法怎么使用

在Java中,抽象类是用来定义一组相关类的共同特征和行为的。抽象类不能被实例化,只能被继承。要定义一个抽象类,需要在类的声明前加上关键字"abstract"。例如:```javaabstract class Animal {// 抽象类可以
2023-08-17

探究PHP中静态方法与抽象方法的特性和用法

PHP中静态方法与抽象方法的特性和用法在PHP编程中,静态方法和抽象方法是两种不同的方法类型,它们在面向对象编程中发挥着重要的作用。本文将探究PHP中静态方法与抽象方法的特性和用法,并提供具体的代码示例。一、静态方法的特性和用法静态方法
探究PHP中静态方法与抽象方法的特性和用法
2024-03-05

Python的类方法与静态方法的使用

本篇内容主要讲解“Python的类方法与静态方法的使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python的类方法与静态方法的使用”吧!在Python语言中有如下3种方法:成员方法类方法(
2023-06-15

Python中静态方法,类方法,属性方法怎么使用

本篇内容介绍了“Python中静态方法,类方法,属性方法怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.静态方法通过@static
2023-06-30

PHP中静态方法和抽象方法的区别及应用场景

PHP中静态方法和抽象方法都是面向对象编程中重要的概念,它们分别有着不同的特点和应用场景。本文将具体介绍PHP中静态方法和抽象方法的区别,并给出相应的代码示例来帮助读者更好地理解这两种方法的用法。一、静态方法静态方法是定义在类中的一个特
PHP中静态方法和抽象方法的区别及应用场景
2024-03-05

PHP编程中静态方法和抽象方法的实际应用对比

PHP编程中静态方法和抽象方法的实际应用对比在PHP编程中,静态方法和抽象方法是两种常用的方法类型,它们在实际应用中有着不同的作用和用法。本文将通过具体的代码示例来对比静态方法和抽象方法的实际应用,帮助读者更好地理解它们的区别与优劣。一
PHP编程中静态方法和抽象方法的实际应用对比
2024-03-05

Golang中的抽象类使用方法详解

Golang中的抽象类使用方法详解在Go语言中,并没有传统意义上的抽象类和接口继承的概念,但是可以通过结构体嵌套和接口组合来实现类似的功能。本文将详细介绍如何在Golang中实现类似抽象类的功能,并通过具体的代码示例进行演示。1. 结构
Golang中的抽象类使用方法详解
2024-03-14

如何在javascript中使用静态方法

这篇文章将为大家详细讲解有关如何在javascript中使用静态方法,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。JavaScript的特点1.JavaScript主要用来向HTML页面添加
2023-06-14

如何在java中使用静态方法

如何在java中使用静态方法?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了面向
2023-06-14

怎么在java中使用静态方法

本篇文章为大家展示了怎么在java中使用静态方法,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Java有哪些集合类Java中的集合主要分为四类:1、List列表:有序的,可重复的;2、Queue队列
2023-06-14

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录