Skip Huffman
Skip Huffman

Reputation: 5449

Can a python descriptor be used to instantiate an attribute in the __init__ of another class?

Or does the attribute have to be defined outside of any class methods?

So my descriptor object is this. The IDN object already has some information about the UserNameField, so I want to use it.

class UserNameElement(basePageElement):
    _testMethodName="UserNameElement Test method"
    def __init__(self, IDN, PTF):
        print "creating UserNameElement"
        self.locator =  IDN.UserNameField()

And here is my calling class. Where I want to instantiate the UserNameElement object

class LoginPageObject(basePageObject):
    _testMethodName="LoginPageObject Test method"
    print "creating LoginPageObject"
    def __init__(self, BaseURL):
        super(LoginPageObject, self).__init__()
        self.username=UserNameElement(IDN=self.IDN, PTF=self.PTF)

It seems that the standard process would put the username= in in the general class definition, like this:

class LoginPageObject(basePageObject):
    _testMethodName="LoginPageObject Test   method"
    username=UserNameElement()
    print "creating LoginPageObject"
    def __init__(self, BaseURL):
        super(LoginPageObject, self).__init__()

But then I don't have the PTF and IDN that I define in the basePageObject class.

What can I do to make those available when the username attribute is created?

Thanks

Upvotes: 0

Views: 905

Answers (2)

Anurag Uniyal
Anurag Uniyal

Reputation: 88737

I am afraid that will not be possible, as your attribute username will be resolved via normal attribute access see http://docs.python.org/howto/descriptor.html#invoking-descriptors

May be you can get away by overriding __getattribute__ and simulating what type.__getattribute__() does

class MyD(object):
    def __init__(self, val):
        self.val = val

    def __get__(self, obj, objtype):
        return self.val

    def __set__(self, obj, val):
        self.val = val

class C(object):
    a = MyD(42)
    def __init__(self):
        self.d = MyD(42)

    def __getattribute__(self, name):
        attr = super(C, self).__getattribute__(name)
        if hasattr(attr, '__get__'):
            return attr.__get__(self, C)
        return attr

c = C()
print c.d
print c.a

Output:

42
42

Upvotes: 3

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798606

Since you probably won't need the username until the object has been instantiated, it's probably best to just make it a property and write a getter for it.

Upvotes: 1

Related Questions