【问题标题】:python class variable in static method静态方法中的python类变量
【发布时间】:2026-01-31 14:00:01
【问题描述】:

[更新]:完整代码

我总是对 pyhton 的静态方法感到困惑 但根据this(最后一个答案),它应该可以工作!

得到错误:

AttributeError: MyConnection 类没有属性'myuser'

class MyConnection:
    def __init__(self, hostname, port, user, password):
        myhostname = hostname
        myport = port
        myuser = user
        mypassword = password
        isisessid = None

    @staticmethod
    def connect():
        my_session = MyConnection()

        headers = {'content-type': 'application/json'}
        headers['Authorization'] = 'Basic ' + string.strip(
            base64.encodestring(MyConnection.myuser + ':' + MyConnection.mypassword))

        body = json.dumps({'username': MyConnection.myuser, 'password': MyConnection.mypassword,
            'services': ['platform', 'namespace']})

        uri = '/session/1/session'

        connection = httplib.HTTPSConnection(MyConnection.myhostname, MyConnection.myport)
        connection.connect()

        try:
            connection.request('POST', uri, body, headers)
            response = connection.getresponse()
            my_session.isisessid = MyConnection.extract_session_id(
                response.getheaders())
        except Exception, e:
            print e
            connection.close()
        except httplib.BadStatusLine, e:
            print e
            connection.close()

        return my_session

【问题讨论】:

  • 这个问题与静态方法无关。错误在你的__init__:*.com/a/18622179/429533
  • @Peter:[OT] 帮自己一个忙,使用requests
  • @spinus:感谢您的建议,这不是我的代码 - 尝试在不重新发明*的情况下制造汽车! ;)

标签: python oop static-methods static-variables


【解决方案1】:

如果属性是静态的,不要在初始化方法中初始化它们,在类级别声明它们外部,而不是在方法级别。

但是你为什么要在初始化器中初始化类属性呢?您创建的每个实例都会覆盖它们的值!

我相信您会混淆 instance 属性和 class 属性的用途。为什么不尝试仅使用实例属性?综合考虑,拥有静态数据不是一个好主意。例如:

class MyConnection:
    def __init__(self, hostname, port, user, password):
        self.myhostname = hostname
        self.myport = port
        self.myuser = user
        self.mypassword = password
    @staticmethod
    def connect():
        my_session = MyConnection()
        print my_session.myuser # just an example

【讨论】:

  • 我正在创建一个类“my_session = MyConnection()”的实例,所以我应该使用它来获取它的变量。呵呵
【解决方案2】:

您必须在类范围(静态属性)或实例范围(在__init__)中定义属性。

所以在类范围内它看起来像:

class Cls(object):
    class_scope_attribute = 1

    @staticmethod
    def method1():
        print Cls.class_scope_attribute

    @classmethod
    def metdho2(cls):
        print cls.class_scope_attribute

    def method3(self):
        print Cls.class_scope_attribute
        print self.__class__.class_scope_attribute

在实例范围内:

class Cls2(object):
    def __init__(self):
        self.instance_scope_attribute

    @staticmethod
    def method1():
        # cannot access the instance_scope_attribute
        pass

    @classmethod
    def method2(cls):
        # cannot access the instance_scope_attribute
        pass

    def method3(self):
        print self.instance_scope_attribute

查看变量名前__init__中的self

因此,您必须添加 self. 或将变量移动到类范围,但要小心,因为类范围属性由所有实例共享。

【讨论】:

    【解决方案3】:

    如果您的目的确实是使connect 成为@staticmethod,则在类级别初始化myhostnamemyportmyusermypassword,例如:

        class MyConnection:
            myhostname= hostnameValue
            myport= portValue
            myuser= userValue
            mypassword= passwordValue
    
            @staticmethod
            def connect():
                my_session = MyConnection()
    
                headers = {'content-type': 'application/json'}
                headers['Authorization'] = 'Basic ' + string.strip( base64.encodestring( MyConnection.myuser + ':' + MyConnection.mypassword ) )
    
                body = json.dumps({'username': MyConnection.myuser, 'password': MyConnection.mypassword,'services': ['platform', 'namespace']})
    
                my_session.connection = httplib.HTTPSConnection(MyConnection.myhostname, MyConnection.myport)
                my_session.connection.connect()
    
        MyConnection.connect()
    

    或者,您可以将它们留在None 中,并在调用connect() 之前给它们一个值。

    如果你想让connect 成为一个实例方法,那么你就差不多了。您只需要删除装饰器@staticmethod,并进行一些其他更改:

        class MyConnection:
            def __init__(self, hostname, port, user, password):
                self.myhostname = hostname
                self.myport = port
                self.myuser = user
                self.mypassword = password
    
            def connect():
                headers = {'content-type': 'application/json'}
                headers['Authorization'] = 'Basic ' + string.strip( base64.encodestring(self.myuser + ':' + self.mypassword) )
    
                body = json.dumps({'username': self.myuser, 'password': self.mypassword, 'services': ['platform', 'namespace']})
    
                connection = httplib.HTTPSConnection(self.myhostname, self.myport)
                connection.connect()
    
        my_session= MyConnection(hostnameValue,portValue,userValue,passwordValue)
        my_session.connect()
    

    【讨论】:

      【解决方案4】:

      classmethodstatic method 无法访问在 __init__() 方法中声明的变量。 因为classmethodstaticmethod 绑定到类而不是类的对象,因此它们采用指向类而不是对象实例的类参数。

      __init__() 创建对象实例,因此__init__() 中声明的变量不能被classmethodstaticmethod 访问,除非它们被声明为类变量。

      他们可以修改适用于类的所有实例的类状态。例如,他们可以修改适用于所有实例的类变量。

      【讨论】: