Why does `type(myField)` return `<type 'instance'>` and not `<type 'Field'>`?
Asked Answered
S

2

48

I am confronted to a python problem. I want to use type() to find out what type of variable I am using. The code looks similar to this one:

class Foo():
       array=[ myField(23),myField(42),myField("foo"), myField("bar")]
       def returnArr(self):
          for i in self.array:
               print type(i)

if __name__ == "__main__":
    a=Foo()
    a.returnArr()

Edit: myField() is a class I defined.

When I ask for the type() I get: <type 'instance'> Now according to 1 this is due to the fact that I use a class element and ask for type() on that. Now what I need is: <type 'int'> for the example: myField(42) and <type 'str'> for myField(foo). How could I acheive that?

EDIT:

def __init__(self, name, default, fmt="H"):
    self.name = name
    if fmt[0] in "@=<>!":
        self.fmt = fmt
    else:
        self.fmt = "!"+fmt
    self.default = self.any2i(None,default)
    self.sz = struct.calcsize(self.fmt)
    self.owners = []

The code is taken from scapy and I try to adapt it.

Skardol answered 12/7, 2011 at 15:33 Comment(6)
type() of what? your question is both unclear and ambiguous.Extempore
Doing this should work, but you need to include more detail. What are myField and foo and bar? Where are they initialized? Simply populating a list with ints and strings and then calling type on it's elements should work.Connotation
Please show us how myField is defined. And could you also explain why foo in myField(foo) should be a string? Did you actually mean "foo"?Northward
@Mr. Shickadance, you are correct, it should work, and it does. I tested this in the REPL with my own definition of class myField, foo, and bar, and it gave the expected results. There's something relevant Steve hasn't told us.Cockleshell
sry for the unclear post, I edited the post. should be clearer now I hope.Skardol
To be clear, my output is <class '__main__.myField'>, which is exactly what I would expect.Cockleshell
H
97

in python 2, all of your classes should inherit from object. If you don't, you end up with "old style classes", which are always of type classobj, and whose instances are always of type instance.

>>> class myField():
...     pass
... 
>>> class yourField(object):
...     pass
... 
>>> m = myField()
>>> y = yourField()
>>> type(m)
<type 'instance'>
>>> type(y)
<class '__main__.yourField'>
>>> 

If you need to check the type of an old-style class, you can use its __class__ attribute, or even better, use isinstance():

>>> m.__class__
<class __main__.myField at 0xb9cef0>
>>> m.__class__ == myField
True
>>> isinstance(m, myField)
True

But... you want to know the type of the argument passed to your class constructor? well, that's a bit out of python's hands. You'll have to know just what your class does with it's arguments.

Hellespont answered 12/7, 2011 at 15:47 Comment(11)
hi, thx for your help. Yeah I want to find out if the content of the array is string or int, It is not helping in my case to know that is is an "instance".Skardol
well, what does myField.__init__() do with it's arguments? does it save it away in an attribute? does it call some other function with that argument? We don't have enough information to answer that question right now.Hellespont
def __init__(self, name, default, fmt="H"): self.name = name if fmt[0] in "@=<>!": self.fmt = fmt else: self.fmt = "!"+fmt self.default = self.any2i(None,default) self.sz = struct.calcsize(self.fmt) self.owners = [] Sry, I don't think I can format it right here :/ The code is from scapy not from me. I just try to adapt it for my needSkardol
@Skardol add it to you question where you can format it correctly. Just edit and expand what you have there.Alpenglow
@steve, is that def __init__ for the same myField you call in your original question? I'm not sure that it is; this function requires two arguments (in addition to self), but you call it with only one. Is there something else you can share?Hellespont
pastebin.com/dzyNU2N1 I put the code of scapy I use here. the Simply replace myField through BitField if you want to test the code. I hope this time I included all the info you need, and sry for the very bad post, I'll do better next time.Skardol
As i said, The class linked in your pastebin post takes three arguments to it's constructor. BitField(foo) is invalid, since you have to supply three arguments (name, default and size), but in your code above, you only supply one.Hellespont
Okay, true. Lets rephrase my question, I'm completely lost atm as you see. So the code I pasted here should work: pastebin.com/jjcXyJcQ (I import scapy in the beginning but only use the file from last post) how would I do to get <type 'int'> of the value 0x0 of the field foo? I guess if I undestand how this is done I can figure out the rest myself.Skardol
It looks like the *Field type fully determines the data type that it wraps. Unfortunately, it appears that library uses old style classes. You could try forking your own version of that library and fix the base class to inherit from object, and then test it out to see if that breaks anything (it likely won't), then type(array[0]) == BitField or some such will give you the type. Doing more than that would really be a "scapy" question, not a "python" question, and you should edit your question to reflect the specific library you need help with.Hellespont
okay, thx. that seems to work, but I still have a problem (I think it is related to python and not scapy). I have: <class 'scapy.fields.BitField'> now, but I don't know how to retreive the type of the second value in that field, I want to check if the second element of a BitField is NoneType or not. any hint on this? Indexing doesn't work :/Skardol
You should ask a new question with your scapy problems. I'm sorry I can't help you with that here.Hellespont
A
0

You are placing myField instances into an array. That is why the type is instance. If you would like to get the int or str type you will need to access that field in your myField instance.

def returnArr(self):
   for i in self.array:
       print type(i.accessor)

i will then be your myField and you should be able to access the int or str with an accessor.

Alpenglow answered 12/7, 2011 at 15:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.