返回顶部
首页 > 资讯 > 后端开发 > Python >关于如何在Python中使用静态、类或
  • 383
分享到

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

静态如何在Python 2023-01-31 08:01:34 383人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

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

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

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

        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://www.cnblogs.com/flash...
推荐阅读:Https://www.roncoo.com/course...

--结束END--

本文标题: 关于如何在Python中使用静态、类或

本文链接: https://lsjlt.com/news/193211.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 关于如何在Python中使用静态、类或
    Python中方法的工作方式方法是存储在类属性中的函数,你可以用下面这种方式声明和访问一个函数 >>> class Pizza(object): ... def __init__(self, size):...
    99+
    2023-01-31
    静态 如何在 Python
  • 关于如何在Python中使用静态、类或抽
    方法是存储在类属性中的函数,你可以用下面这种方式声明和访问一个函数 >>> class Pizza(object): ... def __init__(self, size): ......
    99+
    2023-01-30
    静态 如何在 Python
  • 在Python中使用静态,类或抽象方法
    方法是存储在类属性中的函数,你可以用下面这种方式声明和访问一个函数 >>> class Pizza(object): ... def __init__(self, size): ... ...
    99+
    2023-01-31
    抽象 静态 方法
  • JS中关于Class类的静态属性和静态方法
    目录一、类的两个概念二、对象的两个部分1、属性 2、方法三、静态方法使用:在方法前加上static关键字1、为什么使用静态方法三、总结1、静态属性和非静态属性的区别2.使用...
    99+
    2022-11-13
    JS中Class类 Class类静态属性 Class类静态方法
  • 如何在Python中使用静态变量在计数
    今天,在用Python写一个统计一个文件下有多少文件的小标本时,遇到了一个很棘手的问题。如何在Python中使用静态变量来计数。然后,就在网上一通查找,找的方法都是利用类的方法来实现静态变量。说实话没有看太懂,另外我想如果用类成员当做静态...
    99+
    2023-01-31
    变量 静态 如何在
  • 如何在Unity3D中使用单例模式和静态类
    本篇文章为大家展示了如何在Unity3D中使用单例模式和静态类,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。静态类不能继承和被继承!(严格点说是只能继承System.Object)也就是说你的静态类...
    99+
    2023-06-14
  • 在 PHP 中创建和使用静态类
    在 PHP 中,静态类是在程序中只实例化一次的类。它必须有一个静态成员(variable)、静态成员函数(method),或两者兼有。在 PHP 中使用静态变量创建静态类让我们创建一个类并初始化四个变量。然...
    99+
    2024-02-27
  • 如何在 Linux 中使用动态和静态库
    本篇内容介绍了“如何在 Linux 中使用动态和静态库”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!了解 Linux 如何使用库,包括静态库...
    99+
    2023-06-15
  • 如何在javascript中使用静态方法
    这篇文章将为大家详细讲解有关如何在javascript中使用静态方法,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。JavaScript的特点1.JavaScript主要用来向HTML页面添加...
    99+
    2023-06-14
  • 如何在java中使用静态方法
    如何在java中使用静态方法?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了面向...
    99+
    2023-06-14
  • 如何在PHP中关闭伪静态代代码?
    关闭PHP中的伪静态代代码一直是网站优化中的一个重要环节,本文将介绍如何在PHP中关闭伪静态代代码,并提供具体的代码示例。 首先,我们需要了解什么是伪静态代代码。伪静态代代码是指通过修...
    99+
    2024-04-02
  • 浅谈Android中关于静态变量(static)的使用问题
    项目中,在不停地接收串口数据很长一段时间(几小时)后,会偶然性的报错。初步排除了oom和cpu紧张问题,因为是工业平板不方便调试,用了些比较笨的方法最后锁定在几个用了stati...
    99+
    2022-06-06
    静态 静态变量 static 变量 Android
  • 如何在Python中使用类
    如何在Python中使用类?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、类的定义和使用在C++中,类是“结构体”的衍生。在Python中,类作为一个完全独立...
    99+
    2023-06-15
  • C#中如何使用静态方法
    C#中如何使用静态方法,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。C#静态方法使用中遇到的问题:在源码工程中几乎没有看到什么静态方法,但是在Ms的SQLHelper中几乎全部...
    99+
    2023-06-17
  • C#中如何使用静态变量
    C#中如何使用静态变量,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。C#静态变量的使用实例:在类库中定义了一个静态常量,如下:public const...
    99+
    2023-06-17
  • 关于在Java中使用预定义类
    目录一、对象与对象变量二、Java类库中的LocalDate类三、更改器方法与访问器方法在Java中,没有类就无法做任何事情。然而,并不是所有的类都表现出面向对象的典型特征。以Mat...
    99+
    2023-05-20
    Java 预定义 Java
  • 静态导入机制如何在java项目中使用
    这篇文章给大家介绍静态导入机制如何在java项目中使用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。java中静态导入机制用法实例详解静态常量类在java开发中,我们会经常用到一些静态常量用于状态判断等操作。为了能够在...
    99+
    2023-05-31
    java 静态导入机制 ava
  • PHP中怎么使用self关键字指向类静态变量
    本篇文章为大家展示了PHP中怎么使用self关键字指向类静态变量,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。首先我们要明确一点,self是指向类本身,也就是PHP self关键字是不指向任何已经实...
    99+
    2023-06-17
  • Android静态库如何使用
    要使用Android静态库,需要按照以下步骤进行操作:1. 将静态库文件(通常是以`.a`或`.lib`为后缀)放在你的Androi...
    99+
    2023-08-23
    Android
  • javascript中如何使用class静态方法
    这篇文章将为大家详细讲解有关 javascript中如何使用class静态方法,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。类相当于实例的原型, 所有在类中...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作