静态变量vs类变量vs实例变量vs局部变量

 佳鈺佳琴欣怡 发布于 2023-02-12 11:20

在发布之前,我在这个网站上搜索了超过六个帖子(python变量类静态实例本地) /sf/ask/17360801/?q=python+variables+class+static+instance+local

我为未来的学习添加了几个结果的书签,但是如果我的想法是对或错,他们似乎都没有向我澄清,所以我觉得我可能会遗漏一些基础知识(见下文)......

术语"类变量"和"静态变量"是指同一个东西吗?经过大约三次谷歌搜索,每次搜索我能理解的约6篇文章,我得出的结论是类和静态变量是一回事.但是,由于我只是学习Python和OOP的基础知识,这个结论可能是错误的,所以我想在我继续用错误的思维方式学习之前找到我的推理中的任何缺陷.在下面的代码中:

class Variables():
    scVar = 3

    def __init__(self, a, b):
        self.iVar1 = a
        self.iVar2 = b

    def getLocalVar3(self):
        localVar1 = 17
        localVar2 = 100
        localVar3 = localVar1 + localVar2
        return localVar3

'scVar'既是类变量又是静态变量('class'和'static'变量是同义词)?

第二个问题是澄清我对区分类变量,实例变量和局部变量的理解.在上面的代码中,我认为scVar是一个类变量; iVar1和iVar2是实例变量; 和localVar1,localVar2和localVar3是局部变量.这是正确的说法,还是有些东西我不见了?


谢谢cirosantilli,你链接的那篇文章是我还没见过的文章.我要去看看.我想知道Python的观点,即类变量和实例变量之间没有区别.这个观点是我应该尝试正确理解,作为一个初学者,或者我应该记住这个想法,而不是太担心将我当前的观点与那个调和,直到我变得更有经验?这个问题似乎过于含糊,取决于我目前对Python的理解程度.大多数情况下,我一直在运行类似于原始帖子中的类示例的命令; 在按下[enter]键之前预测输出,然后在不是我预测的情况下研究输出.从那开始,我开始掌握Python中的工作原理.基本上,我刚刚开始瞥见OO如何在Python中工作 - 缓慢但肯定地向前推进.

"但是上面只是惯例:从语言的角度来看,类变量和实例变量之间没有区别." - 只是为了帮助我更好地理解这一点,从语言的角度来看,这部分是什么......有点暗示Python文档在其中的某个地方解释了这个观点?如果是这样,我将重新阅读文档并专门查看这一部分,并尝试使我的思维过程符合它."......类变量和实例变量之间." 那么,即使'classobj'和'instance'可以看到和访问类和实例变量的方式不同,Python的观点是它们之间没有区别?在将来的阅读中我会记住这个想法,这样我就可以摆脱一些混乱.在原始帖子中运行*.py之后,我使用Python 2.7.x在IDLE中获得以下输出(仅包括跟踪错误的最后一行,以提高可读性):

>>> Variables.scVar
3
>>> Variables.iVar1
AttributeError: class Variables has no attribute 'iVar1'
>>> instance = Variables(5, 15)
>>> instance
<__main__.Variables instance at 0x02A0F4E0>
>>> Variables

>>> instance.scVar
3
>>> instance.iVar1
5
>>> instance2 = Variables(25, 35)
>>> instance2.scVar
3
>>> Variables.scVar = Variables.scVar * 100
>>> Variables.scVar
300
>>> instance.scVar
300
>>> instance2.scVar
300
>>> instance.scVar = 9999
>>> Variables.scVar
300
>>> instance.scVar
9999
>>> instance2.scVar
300
>>> type(Variables)

>>> type(instance)

"但是上面只是惯例:从语言的角度来看,类变量和实例变量之间没有区别." - 通过使用原始帖子中的代码,可能有一系列命令说明了这一点吗?我不怀疑你知道你在说什么; 我发现很难将我目前的思维方式与上述陈述相协调.但我觉得如果我能开始看到两种观点之间的差异,那么重要的是"点击".作为对最后几句话的补充,我可能会更多地看到与关于"类变量和实例变量之间没有区别"的陈述相同的行,但前提是我的以下假设是准确的...来自代码在原始帖子(类变量 - 12行)中,是否只有全球和本地两个范围参与该计划?由于我刚刚开始就如何将它们组合起来得出结论,我认为我对范围的有限理解可能使我无法完全理解类变量和实例变量之间没有区别的想法.我现在唯一可以做的就是(只有可能) - 'Python在类变量和实例变量之间没有区别; 但是全局范围和局部范围之间的差异可能使新手认为这两种变量之间存在差异.我不知道,这个声明是否确定了我可能会遇到的潜在"挂断"?


"一切都是一个对象,包括类和整数:" - 我已经多次阅读过.这么多,我认为它是理解OO和Python的核心信念,但它并不是我完全意识到(我认为)的含义的概念.

class Foo():
    integer = 10
    float = 6.37
    string = 'hello'
    boolean = True
    idkyet = None

    def __init__(self):
        self.a = 'iv_a'
        self.b = 'iv_b'
        self.c = 'iv_c'

    def Func(self):
        self.g = 'g'
        h = 'h'
        i = 'i'
        return 'g' + 'h' + 'i'

>>> Foo

>>> type(Foo.integer)

>>> type(Foo.float)

>>> type(Foo.string)

>>> type(Foo.boolean)

>>> type(Foo.idkyet)

>>> type(Foo)

>>> import os
>>> type(os.getcwd() + '\\Test.py')

>>> type(os)

>>> f = Foo()
>>> type(f)

>>> type(f.Func)

>>> type(f.Func())

>>> f.Func
>
>>> Foo.Func

>>> type(f.a)

>>> type(Foo.a)
AttributeError: class Foo has no attribute 'a'
>>> type(Foo.self.a)
AttributeError: class Foo has no attribute 'self'

当我差不多通过这个响应的一半时,不要使用上面的'class Foo():'代码,然后在下面运行命令,我遇到了障碍,并且无法继续处理其他后续问题我几乎没想过.所以,我暂时离开这个问题并开始阅读你发布的'cafepy ...'链接(由Shalabh Chaturvedi提供).这真的很有趣.之前我曾看过这段摘录,但我没有看过整篇文章,但现在看起来比一周前更容易理解了.我想我会读完整件事.不要介意这篇文章的后半部分(在'***'之后),因为我仍然无法确切地指出我想要问的内容.......一切都是一个对象...主要只是对象类型的差异??? ... <这就是我几乎想到如何构建最后一个问题时记下来的注释,但它从来没有出现过结果.我将不得不等到其他"点击",我可以再次看到我的想法.

如果我浏览一下与"MRO",绑定和未绑定方法有关的任何内容,我也会记住停下来重新阅读...我最近一直在接受这三个术语中的一点,就像它一样感觉他们在我学习过程中的未来不会太远.

Ciro Santill.. 5

我相信静态和类变量通常用作同义词.

从会议的角度来看,你对变量的看法是正确的:这就是你应该在大多数时候考虑它们的方法.

但是上面只是约定:从语言的角度来看,类变量和实例变量之间没有区别.

Python不像C++或Java.

一切都是对象,包括类和整数:

 class C(object): pass
 print id(C)
 C.a = 1
 assert C.__dict__['a'] == 1

方法和实例变量之间没有明显的区别:它们只是对象的属性.

因此,实例变量和类变量之间没有语言级别的区别:它们只是不同对象的属性:

实例变量是对象的属性(self)

类变量是Class对象的属性.

真正的魔法发生在.运营商搜索属性的顺序上:

__dict__ 对象

__dict__ 对象的类

MRO到父类

在你将来感到困惑之前,你应该阅读这篇伟大的文章.

还要注意绑定与未绑定的方法.

编辑:尝试通过OP在他的帖子中提出的进一步问题.

哇那么大!我会尝试阅读所有内容,但对于未来,你应该尽量让问题更加完整.更多代码,更少谈话=).你会得到更好的答案.

我是否应该牢记这个想法,而不是过分担心将我目前的观点与那个观点相协调,直到我变得更有经验?":我做的事情.

我觉得有必要.当必要性召唤,或者我不能再采取魔法行为时,我会学习.

有点暗示Python文档在其中的某个地方解释了这个观点?

我不知道文档,但语言本身就是这样.

当然,该语言旨在给人的印象是语法在常见情况下就像在C++中一样,并且它为类添加了一层薄薄的魔法,使其看起来像这样.

但是,由于这不是它真正起作用的方式,因此只能通过考虑C++类语法来解释所有(有用的)行为.

通过使用原始帖子中的代码,是否有一系列命令可以说明这一点?

我不确定它是否可以按顺序说明.关键是:类是对象,它们的属性由点.MRO按与对象属性相同的顺序搜索:

class C(object):
    i_static = 0
    def __init__(self):
        self.i = 1

# i is in the __dict__ of object c
c = C()
assert c.__dict__['i'] == 1
assert c.i == 1

# dot finds i_static because MRO looks at class
assert c.__class__.__dict__['i_static'] == 0
assert c.i_static == 0

# i_static is in the __dict__ of object C
assert C.__dict__['i_static'] == 0
assert C.i_static == 0

# __eq__ is in the dict of type, which is the __class__ of C
# By MRO, __eq__ is found. `C,C` because of bound vs unbound.
assert C.__class__.__dict__['__eq__'](C,C)
assert C == C

是否只有全球和地方参与该计划的两个范围?

这是我不太清楚的一点.

Python中没有全局范围,只有模块级别.

然后在函数内部有一个新的局部范围.

其余的是.查找属性的方式.

无法确切地指出我想要问的问题

问:我能找到类,整数或函数之间的语法差异吗?

如果你认为你找到了一个,请问:嗯,我怎样才能创建一个具有某些属性的对象,这些属性的行为就像那个看起来不像对象的东西一样?

你应该每次都找到答案.

例:

def f(): pass

class C(object): pass

AHA:f不同于c = C()因为我可以做f() but notc()`!

但是,不,这只是f.__class__.__dict__['__call__']属性的定义f,可以通过MRO找到.

但我们也可以这样做c:

class C(object):
    def __call__(self): pass

现在我们可以做到c().

所以他们在这方面并没有什么不同.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有