如何在方法内访问“静态”类变量?

2025-01-13 08:52:00
admin
原创
139
摘要:问题描述:如果我有以下代码:class Foo(object): bar = 1 def bah(self): print(bar) f = Foo() f.bah() 它抱怨NameError:全局名称“bar”未定义如何bar在方法内访问类/静态...

问题描述:

如果我有以下代码:

class Foo(object):
    bar = 1

    def bah(self):
        print(bar)
            
f = Foo()
f.bah()

它抱怨

NameError:全局名称“bar”未定义

如何bar在方法内访问类/静态变量bah


解决方案 1:

不要bar使用self.barFoo.bar。分配给Foo.bar将创建一个静态变量,而分配给self.bar将创建一个实例变量。

解决方案 2:

定义类方法:

class Foo(object):
    bar = 1
    @classmethod
    def bah(cls):    
        print cls.bar

现在,如果bah()必须是实例方法(即可以访问自身),您仍然可以直接访问类变量。

class Foo(object):
    bar = 1
    def bah(self):    
        print self.bar

解决方案 3:

与所有好的例子一样,您简化了实际要做的事情。这很好,但值得注意的是,python在类与实例变量方面具有很大的灵活性。方法也是如此。为了得到一个很好的可能性列表,我建议阅读Michael Fötsch 的新式类介绍,尤其是第 2 至第 6 节。

刚开始时需要花很多功夫记住的一件事是Python 不是 Java。 这可不只是一句陈词滥调。在 Java 中,整个类都会被编译,这使得命名空间解析变得非常简单:在方法之外(任何地方)声明的任何变量都是实例(或者,如果是静态的,则是类)变量,并且可以在方法内隐式访问。

对于 python 来说,主要的规则是按顺序在三个命名空间中搜索变量:

  1. 函数/方法

  2. 当前模块

  3. 内置

{begin pedagogy}

对此有有限的例外。我想到的主要例外是,当加载类定义时,类定义是其自己的隐式命名空间。但这仅在模块加载期间持续,并且在方法内时完全被绕过。因此:

>>> class A(object):
        foo = 'foo'
        bar = foo


>>> A.foo
'foo'
>>> A.bar
'foo'

但:

>>> class B(object):
        foo = 'foo'
        def get_foo():
            return foo
        bar = get_foo()



Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    class B(object):
  File "<pyshell#11>", line 5, in B
    bar = get_foo()
  File "<pyshell#11>", line 4, in get_foo
    return foo
NameError: global name 'foo' is not defined

{end pedagogy}

最后,要记住的是,您确实可以访问任何想要访问的变量,但可能不是隐式访问。如果您的目标简单明了,那么使用 Foo.bar 或 self.bar 可能就足够了。如果您的示例变得越来越复杂,或者您想要做一些像继承这样的奇特的事情(您可以继承静态/类方法!),或者在类本身中引用类名称的想法对您来说似乎是错误的,请查看我链接的简介。

解决方案 4:

class Foo(object):
     bar = 1
     def bah(self):
         print Foo.bar

f = Foo() 
f.bah()

解决方案 5:

bar是您的静态变量,您可以使用来访问它Foo.bar

基本上,您需要用类名来限定您的静态变量。

解决方案 6:

您可以从类的外部或内部通过对象或直接通过类名访问类变量,基本上,您应该直接通过类名访问类变量,因为如果有同名的类和实例变量则同名实例变量优先,而通过对象访问时同名实例变量将被忽略。因此,使用类名访问类变量比使用对象更安全。

例如,您可以通过对象访问类变量,也可以从类外部直接通过类名访问类变量,如下所示:

class Person:
    name = "John" # Class variable

obj = Person()
print(obj.name) # By object
print(Person.name) # By class name

输出:

John
John

但是,如果通过对象添加与类变量同名的实例变量:

class Person:
    name = "John" # Class variable

obj = Person()
obj.name = "Tom" # Adds the same name instance variable as class variable
print(obj.name) # By object
print(Person.name) # By class name

self或者,如果通过以下方式添加与类变量同名的实例变量__init__()

class Person:
    name = "John" # Class variable
    
    def __init__(self, name):
        self.name = name # Adds the same name instance variable as class variable

obj = Person("Tom")
print(obj.name) # By object
print(Person.name) # By class name

同名实例变量在被对象访问时优先:

Tom  # By object
John # By class name

self并且,您还可以从实例方法内部通过类名直接访问类变量,如下所示:

class Person:
    name = "John" # Class variable
        
    def test(self): # Instance method
        print(self.name) # By "self"
        print(Person.name) # By class name

obj = Person()
obj.test()

输出:

John
John

但是,如果通过对象添加与类变量同名的实例变量:

class Person:
    name = "John" # Class variable
        
    def test(self): # Instance method
        print(self.name) # By "self"
        print(Person.name) # By class name

obj = Person()
obj.name = "Tom" # Adds the same name instance variable as the class variable
obj.test()

self或者,如果通过以下方式添加与类变量同名的实例变量__init__()

class Person:
    name = "John" # Class variable
    
    def __init__(self, name):
        self.name = name # Adds the same name instance variable as the class variable
        
    def test(self): # Instance method
        print(self.name) # By "self"
        print(Person.name) # Directly by class name

obj = Person("Tom")
obj.test()

同名实例变量在以下情况下访问时优先考虑self

Tom  # By "self"
John # By class name
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2599  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1556  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。其中,技术评审与决策评审是IPD流程中至关重要的环节,它们既有明显的区别,又存在紧密的协同关系。深入理解这两者的区别与协同,对于企业有效实施IPD流程,提升产品开发效率与质量具有重要意义...
IPD管理流程   38  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、ClickUp、Freshdesk、GanttPRO、Planview、Smartsheet、Asana、Nifty、HubPlanner、Teamwork。在当今快速变化的商业环境中,项目管理软件已成为企业提升效率、优化资源分配和确保项目按时交付的关键工具。然而...
项目管理系统   32  
  建设工程项目质量关乎社会公众的生命财产安全,也影响着企业的声誉和可持续发展。高质量的建设工程不仅能为使用者提供舒适、安全的环境,还能提升城市形象,推动经济的健康发展。在实际的项目操作中,诸多因素会对工程质量产生影响,从规划设计到施工建设,再到后期的验收维护,每一个环节都至关重要。因此,探寻并运用有效的方法来提升建设工程...
工程项目管理制度   28  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用