第二十八篇 静态属性、类方法、静态方法

静态属性

静态属性:实际上说的就是数据属性

需求:每个人都有自己的房子,想知道每个人自己的房子都有多大平米

实现分析:每个人,表示有很多人,不可能一个人写一次计算面积的方法,那么就可以将它提炼出来,放到类里

class Room:
    tag=1
    def __init__(self,name,owner,width,length,heigh):
        self.name=name
        self.owner=owner
        self.width=width
        self.length=length
        self.heigh=heigh

    # 计算面积
    def cal_area(self):
        # print(‘%s 住的 %s 总面积是%s‘ % (self.owner,self.name, self.width * self.length))

# 实例化
R1=Room(‘大House‘,‘alex‘,100,100,100000)
R2=Room(‘小平房‘,‘yuanhao‘,2,4,6)

# 调用计算面积
r1.cal_area()
r2.cal_area()

# alex 住的 大House 总面积是10000
# yuanhao 住的 小平房 总面积是8

  • 静态属性:@property

静态属性是绑定到实例上的,是通过实例.方法名 进行调用的。

静态属性的作用:就是封装逻辑,让用户再调用的时候完全感知不到后端的逻辑,就行在调用一个普通的数据属性一样。

特点:定义一个静态属性,内部会有一个self位置参数,self代表实例,实例可以访问到实例的数据属性,实例同样也可以访问到类的数据属性和类的函数属性,也就是说

静态属性,既可以访问实例属性,也可以访问类的属性(类的数据属性和类的函数属性)--->  self.类属性   或者  self.实例属性

class Room:
    tag=1
    def __init__(self,name,owner,width,length,heigh):
        self.name=name
        self.owner=owner
        self.width=width
        self.length=length
        self.heigh=heigh

    @property   # 属性的意思。
    def cal_area(self):
        return  ‘%s 住的 %s 总面积是%s‘ % (self.owner,self.name, self.width * self.length)   # 需要return值

# 实例化
R1=Room(‘大House‘,‘alex‘,100,100,100000)
R2=Room(‘小平房‘,‘yuanhao‘,2,4,6)

# 调用静待属性时,就不用再加小括号了。
# 调用cal_area,实际上是个函数属性,但是加了@property 之后,再调用,直观感受上就跟调用实例的数据属性是一样的,调用者看不到背后的运行逻辑,# 调用者更不知道调用的这个到底是数据属性还是函数属性----这就是静态属性的作用。
print(R1.cal_area)
print(R2.cal_area)

# 这是实例直接调用实例的数据属性。
print(R1.name)
print(R2.name)
  • 类方法:@calssmethod

不跟任何实例捆绑,只跟类捆绑的方法

作用和目的:跟实例没有任何关系了,只是类级别的操作,类来调用自己的方法。

特点:函数的位置参数默认就被写成了cls, cls代表类, 类能访问到类的数据属性和类的函数属性(---> cls.类属性 或者 cls.实例属性),但是类不能访问到实例的属性。

需求:
类调用类的函数属性

class Room:
    tag=1  # 类的数据属性
    def __init__(self,name,owner,width,length,heigh):
        self.name=name
        self.owner=owner
        self.width=width
        self.length=length
        self.heigh=heigh

    @property
    def cal_area(self):
        return ‘%s 住的 %s 总面积是%s‘ % (self.owner, self.name, self.width * self.length)

    def test(self):
        print(‘from test‘,self.name)

# 1. 类可以调用自己(类)的数据属性
print(Room.tag)   # 1

# 2.  类调用自己(类)的函数属性
#  如果没有实例,直接调用函数属性
Room.test(r1)     # 1.name
# AttributeError: ‘int‘ object has no attribute ‘name‘

# 报错了,因为函数属性test(self), self指的就是实例,需要传入实例参数才能正常运行。所以要先实例化
r1=Room(‘大House‘,‘alex‘,100,100,100000)
Room.test(r1)     # r1.name
#from test 大House

没有类方法之前的这种方案,必须通过实例才能调用到

使用类方法,就可以不再通过实例,而可以直接调用类的函数属性了。

class Room:
    tag=1  # 类的数据属性
    def __init__(self,name,owner,width,length,heigh):
        self.name=name
        self.owner=owner
        self.width=width
        self.length=length
        self.heigh=heigh

    @property   # 静态属性
    def cal_area(self):
        return ‘%s 住的 %s 总面积是%s‘ % (self.owner, self.name, self.width * self.length)

    def test(self):
        print(‘from test‘,self.name)

    @classmethod  # 类方法:就把tell_info变成专门供类使用的方法
    def tell_info(cls,x):   # cls:本质上就是一个位置参数,但是python告诉你,cls接收的是一个类名,而这个类名是默认传的,不需要你再显示的写出来然后传进来
        # 打印类名
        print(cls)     # 运行结果:<class ‘__main__.Room‘>  class表示类型是类,__main__表示当前文件,Room表示类名
        # cls.tag:类调用类的数据属性。
        print(‘--》‘,cls.tag)  # 相当于print(‘--》‘,Room.tag)

# 调用方式:类名.函数属性
# tell_info(cls,x): 有两个参数:第一个是位置参数cls,第二个是x
# 可以为什么只传了一个参数12呢?因为该函数属性已经变成了类方法,第一个参数cls Python默认就给你传成了类名Room
# 与self道理一样一样的。所以,调用者只需要传入第二个位置参数就可以拉。
Room.tell_info(12)
# 结果
<class ‘__main__.Room‘>
--》 1

看到了把,用了类方法,类想调用类的函数属性,就不比再通过实例这个中介来调用了,而是可以直接调用。

注意:

# 通过实例也可以调用类方法

r1=Room(‘大House‘,‘alex‘,100,100,100000)
r1.tell_info(13)

# 结果
<class ‘__main__.Room‘>
--》 1 13

# 但是,前面说过了,@classmethod 就是专门供类使用的,所以,虽然能通过实例调用,但是千万别这么干,别给自己找不痛快

注意,千万别给自己找别扭

  • 静态方法:@staticmethod

@staticmethod,不跟类绑定,也不跟实例绑定,只是一个类的工具包

用处:只是名义上归属类管理,不能使用类变量和实例变量,是类的工具包

特定:函数里既没有self参数,也没有cls参数,所以静态方法不能访问类属性和实例属性

class Room:
    tag=1
    def __init__(self,name,owner,width,length,heigh):
        self.name=name
        self.owner=owner
        self.width=width
        self.length=length
        self.heigh=heigh

    @property
    def cal_area(self):
        return ‘%s 住的 %s 总面积是%s‘ % (self.owner, self.name, self.width * self.length)

    @classmethod
    def tell_info(cls,x):
        print(cls)
        print(‘--》‘,cls.tag,x)    #print(‘--》‘,Room.tag)

    @staticmethod     # static:静态  staticmethod 就是类的工具包
    def wash_body(a,b,c):
        print(‘%s、 %s、 %s正在洗澡‘ %(a,b,c))

  # 通俗的说,静态方法里没有self或者cls等位置参数,让你可以向类方法或者self那样,通过点的方式调用类变量,比如:通过cls.tag这样的方式进行调用类变量
      # 在类里,这么写是没有任何实际意义的, 所以,此处这么写就是为了提示自己,这是无意义的,以后开发中别这么干
    def test(x,y):
        print(x,y)

# @staticmethod 既可以通过类调用,也可以通过实例调用
# 1. 调用方式:  类名.函数属性名
Room.wash_body(‘alex‘,‘yuanhao‘,‘wupeiqi‘)

# 2. 调用方式:  实例.函数属性名
r1=Room(‘厕所‘,‘alex‘,100,100,100000)
r1.wash_body(‘alex‘,‘yuanhao‘,‘wupeiqi‘)

# 那不加@staticmethod,有什么区别呢?
# 1. 通过类调用test()函数,可以调用
Room.test(1,2)
# 1 2

# 2. 通过实例调用test()函数,不可以调用,因为实例调用需要会自动把实例自己传给函数,而test()却没有self接收。
r1.test(1,2)
# TypeError: test() takes 2 positional arguments but 3 were given

问题:那静态方法到底定义到哪里去了呢?

【答】静态属性@property、类方法@classmethod、静态方法@staticmethod, 都是定义到了类的数据字典里的。

print(Room.__dict__)

# {‘__module__‘: ‘__main__‘, ‘tag‘: 1, ‘__init__‘: <function Room.__init__ at 0x019A1C00>, ‘cal_area‘: <property object at 0x0193CDE0>, ‘tell_info‘: <classmethod object at 0x017993B0>, ‘wash_body‘: <staticmethod object at 0x019A5190>, ‘test‘: <function Room.test at 0x019A1AE0>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘Room‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘Room‘ objects>, ‘__doc__‘: None}

# 通过上面可以看到,静态属性@property、类方法@classmethod、静态方法@staticmethod, 都是定义到了类的数据字典里的。
print(r1.__dict__) # {‘name‘: ‘厕所‘, ‘owner‘: ‘alex‘, ‘width‘: 100, ‘length‘: 100, ‘heigh‘: 100000} #实例始终不变的就是只有自己的数据属性

小总结:

1、函数属性有参数self:表示该函数属性跟实例绑定

2、@classmethod,函数属性有参数cls:表示该函数属性跟类绑定

3、@staticmethod,函数属性既没有self参数,也没有cls参数:表示该函数属性既不跟类绑定,也不跟实例绑定,只是一个类的工具包

原文地址:https://www.cnblogs.com/victorm/p/9314241.html

时间: 2024-08-28 21:41:35

第二十八篇 静态属性、类方法、静态方法的相关文章

Egret入门学习日记 --- 第二十八篇(书中 9.19 ~ 9.19 节 内容)

第二十八篇(书中 9.19 节 内容) 没想到第九章的组件篇可真是够长的,没事,慢慢来吧. 开始 9.19节. 重点: 1.创建一个Tips提示组件. 操作: 1.创建一个Tips提示组件. 哇!出大问题!这个Tips组件有点牛皮!怎么办? 书中内容这部分,我直接懵逼. 还有这部分也是. 一点一点来分析好吧. 好,开始分析一波. 第一步:查看最终展示效果. 这是最终效果.(我去,我现在才知道,原来博客园的编辑器还可以放Gif图片...) 第二步:这个黑色的弹框组件本质上是由什么构成的? 可见,在

python的类的 静态属性 类方法 静态方法

一.静态属性 静态属性说的就是数据属性 1.定义一个房间的类,求下这个房间的面积 class Room: def __init__(self,name,ower,width,length,heigh): self.Name=name self.Ower=ower self.Width=width self.Length=length self.Heigh=heigh r1=Room("厕所","北爷",2,2,20000)#实例化出来一个实例r1,实例化的过程就是执

第二十八篇: 学习笔记

最近一直在学一些零零碎碎的东西, 首先,将<鸟哥的 Linux 私房菜 -- 基础学习篇>过了一遍. 因为有了Windows驱动,PCI/PCIe, USB, xHCI, Windows内核编程的基础, 加上自己以前也动手写过Linux设备驱动, 研究过Makefile, KConfig, make menuconfig, GIT的部分内容 鸟哥的这本书确实写得非常通俗易懂,帮我解开了一些以前知道怎么操作, 但不知道为什么要这样操作的疑惑. 另外,基本完成了USB Audio/Video Cl

Python之路【第二十八篇】:django视图层、模块层

1.视图函数 文件在view_demo 一个视图函数简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何东西都可以.无论视图本身包含什么逻辑,都要返回响应.代码写在哪里也无所谓,只要它在你的Python目录下面.除此之外没有更多的要求了——可以说“没有什么神奇的地方”.为了将代码放在某处,约定是将视图放置在项目或应用程序目录中的名为views.py的文件中. 视图

第二十八篇:SOUI中自定义控件开发过程

在SOUI中已经提供了大部分常用的控件,但是内置控件不可能满足用户的所有要求,因此一个真实的应用少不得还要做一些自定义控件. 学习一个新东西,最简单的办法就是依葫芦画瓢.事实上在SOUI系统中内置控件和自定义控件的开发流程是完全一样的,因此只需要打开SOUI的源代码,随便找一个控件看一下就大体差不多了. 下面我以controls.extend目录下的的SRadioBox2控件为例对控件开发过程需要注意的地方做一点说明. 要开发一个控件,首先要确定的是应该从哪个控件来继承.选择一个合适的基类是正确

小刘同学的第二十八篇博文

今天状态不是很好,不知道怎么的,坐在椅子都感觉很难受,难得晚上吃的麻辣香锅有毒? 特别难受,一阵阵的恶心,强打起精神来,把16次课的最后一道逻辑题写完了,其实这个挺简单的,不过没思考,很简单的用了很多ifififif-- 应该可以少用点if,逻辑应该会更好看一点,实在是头晕恶心,就没多想,写完了就行吧-- <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"

我的第二十八篇博客---seleinum

from selenium import webdriver #初始化驱动driver=webdriver.Chrome()#请求页面driver.get(url='https://www.baidu.com')#找到对应标签,发送文本driver.find_element_by_xpath("//*[@id='kw']").send_keys('2019') #找到按钮,点击clickdriver.find_element_by_xpath("//*[@id='su']&q

开始写游戏 --- 第二十八篇

今天: 1.添加:物品奖励组件 2.添加:物品信息弹框组件 3.碰到BUG,现在被卡住了 上图: 1.添加:物品奖励组件 { 效果: 代码: } 2.添加:物品信息弹框组件 { 效果: 代码: 要使用这个组件的话,还要搭配一个数据转换类: } 3.碰到BUG,现在被卡住了 { 可以看到,物品信息组件显示位置出现问题. 这个FGUI官方群,现在都没有给具体的解决方案. 这是在FGUI编辑器中的效果: 这是游戏运行的效果: 为了证明是同一个组件,我特意换了一下颜色: 可见,现在这种情况...我真的有

Python之路【第十八篇】:Web框架们

Python之路[第十八篇]:Web框架们 Python的WEB框架 Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Python的标准库外,其不依赖任何其他模块. 1 2 3 4 pip install bottle easy_install bottle apt-get install python-bottle wget http://bottlepy.org/bottle.py Bottle框架大致可以分为以下部分: 路