переменная класса python в статическом методе

[обновлено]: Полный код

Я всегда путаюсь со статическими методами 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

person Peter    schedule 04.09.2013    source источник
comment
Этот вопрос не имеет ничего общего со статическими методами. Ошибка в вашем __init__: stackoverflow.com/a/18622179/429533   -  person Jace Browning    schedule 04.09.2013
comment
@Peter: [OT] сделайте себе одолжение и используйте запросы   -  person spinus    schedule 05.09.2013
comment
@spinus: Спасибо за предложение, это не мой код — пытаться построить машину, не изобретая колеса! ;)   -  person Peter    schedule 05.09.2013


Ответы (4)


Если атрибуты будут статическими, не инициализируйте их в методе инициализатора, объявите их вне на уровне класса, а не на уровне метода.

Но почему вы инициализируете атрибуты класса в инициализаторе? каждый созданный вами экземпляр перезапишет свои значения!

Я полагаю, вы путаете, для чего используются атрибуты экземпляра и атрибуты класса. Почему бы вам не попробовать использовать только атрибуты экземпляра? учитывая все обстоятельства, иметь статические данные не хорошая идея. Например:

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
person Óscar López    schedule 04.09.2013
comment
Я создаю экземпляр класса my_session = MyConnection(), поэтому я должен использовать его для получения его переменных. угу - person Peter; 04.09.2013

Вы должны определить атрибуты в области класса (статические атрибуты) или в области экземпляра (в __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

Посмотрите на self в __init__ перед именем переменной.

Итак, вам нужно добавить self. или переместить переменные в область класса, но будьте осторожны, поскольку атрибуты области класса являются общими для всех экземпляров.

person spinus    schedule 04.09.2013

Если ваша цель действительно состоит в том, чтобы сделать connect @staticmethod, тогда инициализируйте myhostname, myport, myuser и mypassword на уровне класса, например:

    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()
person Mario Rossi    schedule 04.09.2013

classmethod и static method не могут получить доступ к переменным, объявленным в методе __init__(). Поскольку classmethod и staticmethod привязаны к классу, а не к объекту класса, следовательно, они принимают параметры класса, которые указывают на класс, а не на экземпляр объекта.

__init__() создает экземпляр объекта, поэтому переменные, объявленные в __init__(), не могут быть доступны classmethod и staticmethod, если только они не объявлены как переменные класса.

Они могут изменить состояние класса, которое будет применяться ко всем экземплярам класса. Например, они могут изменить переменную класса, которая будет применяться ко всем экземплярам.

person shivaraj karki    schedule 04.09.2020