Question

[updated]: Full code

I always get confused with pyhton's staticmethods but according to this (last answer), it should work!

getting error:

AttributeError: class MyConnection has no attribute '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
Was it helpful?

Solution

If the attributes are going to be static, don't initialize them in the initializer method, declare them outside at the class level, not at method level.

But why are you initializing class attributes in the initializer? every instance that you create will overwrite their values!

I believe you're confusing what instance attributes and class attributes are used for. Why don't you try using only instance attributes? all things considered, having static data is not a good idea. For example:

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

OTHER TIPS

You have to define attributes in a class scope (static attributes) or in instance scope (in __init__).

So in class scope it looks like:

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

In instance scope:

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

Look at the self in __init__ before variable name.

So, you have to add self. or move variables to class scope, but be careful as class scope attributes are shared by all instances.

If your purpose is really to make connect a @staticmethod, then initialize myhostname,myport, myuser, and mypassword at the class level, like in:

    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()

Alternatively, you can leave them in None and give them a value before calling connect().

If you want to make connect an instance method, then you are pretty much there. You just need to remove decorator @staticmethod, and do a few other changes:

    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()

classmethod and static method cannot access varibles declared in __init__() method. Because classmethod and staticmethod bound to the class and not the object of the class, hence they take class parameters that points to the class and not the object instance.

__init__() creates object instance, hence variables declared in __init__() cannot be accessed by classmethod and staticmethod, unless they are declared as class variables.

They can modify a class state that would apply across all the instances of the class. For example they can modify a class variable that will be applicable to all the instances.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top