Python中静态方法中的类变量

3

[更新]: 完整代码

我总是对Python的staticmethod感到困惑,但根据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

1
这个问题与静态方法无关。错误在于你的__init__函数:https://dev59.com/dnbZa4cB1Zd3GeqPGHq1#18622179 - Jace Browning
@Peter:[OT] 给自己一个好处,使用requests - spinus
@spinus:感谢您的建议,这不是我的代码 - 我试图在不重新发明轮子的情况下构建一辆汽车!;) - Peter
4个回答

7
如果属性是静态的,请勿在初始化方法中初始化它们,在类级别而不是方法级别上声明它们。但是为什么要在初始化器中初始化类属性?您创建的每个实例都会覆盖它们的值!我认为您正在混淆实例属性和类属性的用途。为什么不尝试仅使用实例属性?毕竟,具有静态数据并不是一个好主意。例如:
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()",所以我应该使用它来获取它的变量。显然。 - Peter

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.或将变量移动到类范围内,但要小心,因为类范围属性由所有实例共享。


2

如果您的目的是将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()

0

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

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接