面向对象之类方法、静态方法和属性

类方法

什么是类方法?

类方法是通过类名直接调用的方法,类方法至少有一个参数,第一个参数默认cls(也就是类名),当然对象名也可以调用类方法,但一般不这么用。

class A:
    name = "barry"

    def func1(self):
        print(self)

    @classmethod     # 类方法
    def func2(cls):
        print(cls)

A.func2()     # <class ‘__main__.A‘>

a = A()
a.func1()     # <__main__.A object at 0x00000200B267C978>
a.func2()     # <class ‘__main__.A‘>

类方法的应用场景

类方法是将类本身作为对象进行操作的方法。假设有个方法,且这个方法在逻辑上采用类本身作为对象来调用更合理,那么这个方法就可以定义为类方法。另外,如果需要继承,也可以定义为类方法

静态方法

什么是静态方法?

静态方法是类中的函数,不需要实例化(不需要传入self和各种参数)。

静态方法的应用场景

静态方法主要用于存放逻辑性的代码,逻辑上属于类,但是和类本身没有关系,也就是说在静态方法中,不会涉及到类中的属性和方法的操作。可以理解为,静态方法是个独立、单纯的函数,它仅仅托管与某个类的名称空间中,便于使用和维护。

比如说,我们想写一个关于时间操作的类,其中有一个获取当前格式化时间的方法

import time

class TimeOperate(object):
    def __init__(self, hour, minute, second):
        self.hour = hour
        self.minute = minute
        self.second = second

    @staticmethod
    def showtime():
        return time.strftime("%H:%M:%S", time.localtime())

print(TimeOperate.showtime())    # 20:46:54

t = TimeOperate(18, 10, 28)
current_time = t.showtime()
print(current_time)    # 20:46:54

虽然我们也可以在外面定义一个方法来实现同样的功能,但是这样就打乱了逻辑关系,使代码维护起来变得困难

属性(property)

什么是属性?

property是一类特殊的属性,访问时会自动执行一段代码(方法)并返回值,通俗的理解就是property是伪装成属性的方法。

下面我们来看一个例子,我们要定义一个人类,要求能够获取到一个人的BMI指数,如果不用property,代码是这样的

 1 class Person(object):
 2     def __init__(self, name, weight, height):
 3         self.name = name
 4         self.weight = weight
 5         self.height = height
 6
 7     def bmi(self):
 8         return self.weight/(self.height**2)
 9
10
11 p1 = Person("李小龙", 70, 1.80)
12 print(p1.bmi())    # 21.604938271604937

虽然这样也可以实现功能,但是不太符合人类是习惯,因为在我们看来,BMI应该是一个静态的属性,就和身高体重一样,应该用对象名.  的方式访问,用property就可以实现,优化后的代码如下

class Person(object):
    def __init__(self, name, weight, height):
        self.name = name
        self.weight = weight
        self.height = height

    @property   # 将bmi伪装成属性
    def bmi(self):
        return self.weight/(self.height**2)

p1 = Person("李小龙", 70, 1.80)
print(p1.bmi)     # 这里p1.bmi实际上是执行bmi方法然后返回值给p1.bmi

使用property的好处

将一个类的方法定义成属性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除

class Goods(object):
    def __init__(self, name, original_price, discount):
        self.name = name
        self.original_price = original_price
        self.discount = discount

    @property
    def price(self):
        return self.original_price*self.discount

    @price.setter
    def price(self, new_original_price):
        self.original_price = new_original_price

    @price.deleter
    def price(self):
        del self.original_price

tomato = Goods("西红柿", 3, 0.9)
print(tomato.price)    # 2.7

# tomato.price = 3.5    # 原价改为3.5
# print(tomato.price)   # 3.15

del tomato.price     # 删除
print(tomato.price)     # RecursionError: maximum recursion depth exceeded

原文地址:https://www.cnblogs.com/zzliu/p/10284809.html

时间: 2024-08-30 18:36:00

面向对象之类方法、静态方法和属性的相关文章

python学习笔记之面向对象中的静态方法、类方法、属性方法总结

静态方法 类方法 属性方法 一.静态方法 可以利用@staticmethod装饰器把一个方法变成一个静态方法.静态方法不可以方法实例变量或者类变量,也就是说不可以使用self.属性这样子调用实例属性了.其实静态方法就和类本身没什么关系了,它和类 唯一的关联就是需要通过类名来调用这个方法. 错误调用方式: class Dog(object): def __init__(self,name): self.name = name @staticmethod #把eat方法变为静态方法 def eat(

Python之路-面向对象&amp;继承和多态&amp;类属性和实例属性&amp;类方法和静态方法

一.面向对象 编程方式 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强-" 什么是面向对象 面向对象就不像面向过程那样按照功能划分模块了,它所关注的是软件系统有哪些参与者,把这些参与者称为对象,找出这些软件系统的参与者也就是对象之后,分析这些对象有哪些特征.哪些行为,以及对象之间的关系,所以说面向对象的开发核心是对象 什么是类 面向对象编程的两个重要的概念:类和对象 类是

ExtJS学习-------Ext.define的别名和备用名,两种定义静态方法的方法,混入属性和其他属性

(1)Ext.define起别名和备用名 Ext.onReady(function(){ Ext.define('User',{ config:{ name:'张三', age:23 }, //使用别名 alias:'alias_user', //使用备用名 alternateClassName:'alternateClassName_user', constructor:function(config){//构造器 var me=this; me.initConfig(config); } }

coffeescript 继承、私有方法、私有属性、公共方法、公共属性、静态方法、静态属性实现

class Parent constructor: -> _privateAttr = 'privateAttr' _privateFun = ()-> console.log "Parent::privateFun log #{_privateAttr}" publicAttr: 'publicAttr' publicFun: ()-> _privateFun() console.log "Parent::publicFun log #{@publicAt

Objective-C的面向对象中,类有真正的私有方法和私有属性么?

在Java/C#等面向对象语言中,方法的访问权限可以通过public/private/protected来控制其访问权限.而在OC中,方法却并没有访问修饰符.那么,我们有没有办法使其方法变为私有? 1. 如果一个方法不在头文件中声明,那么这个方法在编译期,通过[receiver MethodName]的形式向对象发送消息,编译器会有警告,告诉你未找到该方法,但是实际运行时,依然可以正常运行 原因:编译时,即使这个方法不在头文件中声明,编译器仍然会将方法的签名编译进类的方法列表中, 发送消息时,会

疯狂java学习笔记之面向对象(三) - 方法所属性和值传递

方法的所属性: 从语法的角度来看:方法必须定义在类中 方法要么属于类本身(static修饰),要么属于实例 -- 到底是属于类还是属于对象? 有无static修饰 调用方法时:必须有主调对象(主语,调用者) 1 public class MathTest{ 2 public static void main(String[] args){ 3 System.out.println(Math.sin(1.57)); 4 System.out.println(Math.sin(Math.PI/2))

PHP OOP面向对象部分方法归总(代码实例子)

<?php//对象名存在栈内存中,数据存在堆内存中class leyangjun{    var $name;  //定义变量    var $age;    var $sex;        function say(){//定义方法        echo '哇咔咔';    }        //调用内部属相 或 方法 都用$this    function runMethods(){        echo '<br>我的名字叫:'.$this->name;  //$thi

深入理解javascript中实现面向对象编程方法

介绍Javascript中面向对象编程思想之前,需要对以下几个概念有了解: 1. 浅拷贝和深拷贝:程序在运行过程中使用的变量有在栈上的变量和在堆上的变量,在对象或者变量的赋值操作过程中,大多数情况先是复制栈上的信息,这样就会出现以下情况,如果变量是对象,那么这一操作,复制的只是真正对象所在 的堆内存空间的起始地址,这就是所谓的浅拷贝,如果是深拷贝,则是在内存堆空间中重新分配一个内存,并把分配的内存的起始地址复制过去. 2. 引用类型数据和值类型数据:谈到引用类型数据和值类型数据,自然而然的联想到

【第二周作业】面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别在哪里?

书上的一些概念这里不再复述,仅谈谈自己通过阅读教材.上课听讲后自己的一些理解: 面向过程分析方法注重自顶向下,逐层分析,把整个软件系统的功能逐布分解,各个击破.可以用生活中的一个例子来加以理解——去食堂吃饭.到达食堂(比如琴湖食堂)后,要遵从排队——打饭——阿姨打菜——拿筷子——找位子坐好——开吃,整个过程强调顺序性,比如不拿筷子就坐下是不行的,除非拿手抓.面向过程就是将软件系统所需要实现的功能按照以上类似的思路逐步细分,一步一步要做什么都要分析清楚. 面向对象分析方法则注重分析整个系统的逻辑结