How to check a dictionary for a class object value? - python

I have a dictionary, named
descendDict
And it contains 4 keys which are class objects, which have values that are both letters and other class objects.
Now what I'm trying to do is sort through the dictionary, and call out different actions if the value brought up in the dictionary is a class object, or if it is a letter:
for x in descendDict:
print x, descendDict[x]
for y in descendDict[x][0]:
if y != (classObject?):
#Action
for x in descendDict:
for z in descendDict[x][0]:
if z != (classObject?):
if y == z:
dist = 0
else:
dist = float(nodeDict[y]) + float(nodeDict[z])
In the if statements:
if... != (classObject?):
I am trying to determine whether the variable in the dictionary is, or is not a class object, but i just dont know how to do this.
Here is one the entries:
<__main__.Node instance at 0xb6738> ([<__main__.Node instance at 0xb6710>, 'A', <__main__.Node instance at 0xb6760>], '0.1')
I am sorting through it's first keys list, but i am trying to figure out if the values in the list are a class object, or a letter.

Not sure what you mean by "class object" since everything in Python is a first-class object. If you're trying to figure out if it's an instance of a specific class you can just use isinstance
if isinstance(y, someClass):
# do stuff

its better to define a method in your class then say
if hasattr(d[x],myClassMethodName):#then do this
else:#not a member
this method of checking allows much greater flexibility
for #RussellBorogove
try:
d[x].myMethod(*args,**kwargs)
except:
print "This is not an instance of my class and maybe a letter"

You probably want isinstance(x,type):
x = str
isinstance(x, type)
#=> True
class x(object):pass
isinstance(x, type)
#=> True
class x:pass
isinstance(x, type)
#=> False
x = "foo"
isinstance(x, type)
#=> False
Obviously, you'll have to stick to new-style classes, but you should be anyway.
However, it sounds like you're somehow trying to create your own object dispatch system. I strongly recommend that you move to some kind of common base class for all of your objects, and use method dispatch combined with higher-order methods to achieve whatever you're trying to do.

In Python it's common to use the "easier to ask forgiveness than permission" (EAFP) model, which looks like:
for y in collection:
try:
# treat it like it's a Node
y.actionMethod()
except AttributeError:
# that method doesn't exist, so it's not a Node
# do something else with it
print y
This is preferred over using isinstance(), because it allows you to define several otherwise unrelated classes each with their own actionMethod() without having to change this dispatch code.

Related

Determine if a variable is an instance of any class

How to determine if a variable is an instance in Python 3? I consider something to be an instance if it has __dict__ attribute.
Example:
is_instance_of_any_class(5) # should return False
is_instance_of_any_class([2, 3]) # should return False
class A:
pass
a = A()
is_instance_of_any_class(a) # should return True
I have seen messages about using isinstance(x, type) or inspect.isclass(x) but this would give True for the class (A), not the instance.
I think your understanding of what an instance is wrong here, since everything is an object in python, so 5 is an object of class int and [2,3] is an object of class list and so on.
isinstance(x, y) is the way to go if you just want to check if x is an object of y, but if you want to check if x is an object of builtin class or your own custom defined class then you should be checking the existence of __dict__ using hasattr(x, '__dict__').

Is an instance of object (but not a subclass) guaranteed to compare unequal to any other object?

Apologies if this is a dupe. (I couldn't find it but I'm not very good with google.)
I just stumbled over some code where they use
x = object()
in a place where they probably want x to compare not equal to anyhing that's already there. Is that guaranteed by the language?
If you compare it by using x == other_object, then this might return True. Since a custom class can override the __eq__ function, and make it for instance equal to every other object.
But we can use is to check whether the two operands refer to the same object. So we can for instance use it like:
dummy = object()
lookup = somedict.get(somekey, dummy):
if lookup is dummy:
# we did *not* find the key in the dictionary
pass
else:
pass
Since we just created the dummy object, there is no way that object can be in the somedict (unless it is of course something like locals()), so as a result we know for sure that if we find the key in the dictionary, then it will not return dummy. So we can use is safely to determine that.
Nothing is guaranteed. You can make anything equals to anything else by implementing __eq__.
Unless you know what x is, nothing is guaranteed and nothing can be assumed.
For example:
class A:
def __eq__(self, other):
return True
print(A() == object())
# True
And the contrary:
class A:
def __eq__(self, other):
return False
print(A() == object())
# False

what is meaning of string inside array python

What does "CmdBtn['menu'] = CmdBtn.menu" in second last line mean.
def makeCommandMenu():
CmdBtn = Menubutton(mBar, text='Button Commands', underline=0)
CmdBtn.pack(side=LEFT, padx="2m")
CmdBtn.menu = Menu(CmdBtn)
...
...
CmdBtn['menu'] = CmdBtn.menu
return CmdBtn
When you use x[y] = z, it calls the __setitem__ method.
i.e.
x.__setitem__(y, z)
In your case, CmdBtn['menu'] = CmdBtn.menu means
CmdBtn.__setitem__('menu', CmdBtn.menu)
The Menubutton class does indeed provide a __setitem__ method. It looks like this is used to set a "resource value" (in this case CmdBtn.menu) for the given key ('menu').
This is not a "string inside an array".
The brackets operator is used for item access in some kind of sequence (usually a list, or a tuple), mapping (usually a dict, or dictionary), or some other kind of special object (such as this MenuButton object, which is not a sequence or a mapping). Unlike in some other languages, in python, ANY object is allowed to make use of this operator.
A list is similar to an "array" in other languages. It can contain a mixture of objects of any kind, and it maintains the order of the objects. A list object is very useful for when you want to maintain an ordered sequence of objects. You can access an object in a list using its index, like this (indexes start at zero):
x = [1,2,3] # this is a list
assert x[0] == 1 # access the first item in the list
x = list(range(1,4)) # another way to make the same list
A dict (dictionary) is useful for when you want to associate values with keys so you can look up the values later using the keys. Like this:
d = dict(a=1, b=2, c=3) # this is a dict
assert x['a'] == 1 # access the dict
d = {'a':1, 'b':2, 'c':3} # another way to make the same dict
Finally, you may also encounter custom made objects that also use the same item-access interface. In the Menubutton case, ['menu'] simply accesses some item (defined by the tkinter API) that responds to the key, 'menu'. You can make your own object type with item-access, too (python 3 code below):
class MyObject:
def __getitem__(self, x):
return "Here I am!"
This object doesn't do much except return the same string for key or index value you give it:
obj = MyObject()
print(obj [100]) # Here I am!
print(obj [101]) # Here I am!
print(obj ['Anything']) # Here I am!
print(obj ['foo bar baz']) # Here I am!
First of all, in Python everything is an object and square brackets means that this object is subscriptable (for e.g. tuple, list, dict, string and many more). Subscriptable means that this object at least implements the __getitem__() method (and __setitem__() in your case).
With those methods it's easy to interact with class members, so don't afraid to build your own example, to understand someone else's code.
Try this snippet:
class FooBar:
def __init__(self):
# just two simple members
self.foo = 'foo'
self.bar = 'bar'
def __getitem__(self, item):
# example getitem function
return self.__dict__[item]
def __setitem__(self, key, value):
# example setitem function
self.__dict__[key] = value
# create an instance of FooBar
fb = FooBar()
# lets print members of instance
# also try to comment out get and set functions to see the difference
print(fb['foo'], fb['bar'])
# lets try to change member via __setitem__
fb['foo'] = 'baz'
# lets print members of instance again to see the difference
print(fb['foo'], fb['bar'])
It is shorthand for CmdBtn.configure(menu=CmdBtn.menu)
The way to set widget options is typically at creation time (eg: Menubutton(..., menu=...)) or using the configure method (eg: CmdBtn.configure(menu=...). Tkinter provides a third method, which is to treat the widget like a dictionary where the configuration values are keys to the dictionary (eg: CMdBtn['menu']=...)
This is covered in the Setting Options section of the official python tkinter documentation

Python: asking if two objects are the same class

I have a class Animal and other animals inherit from it (e.q. Sheep, Wolf).I want to check if two objects are the same class and if so, it should create new object of the same class and if they are not, they are fighting.
if x and y same object:
#create new object
else:
#fight
Is there a better method than isinstance?
Because, there will be more animals than just 2 and I think it wouldn't be efficient to do it like this:
if isinstance(x, Wolf)
# ...
you can simply use
if type(x) == type(y):
fight()
Python has a type system that allows you to do exactly that.
EDIT: as Martijn has pointed out, since Types only exist once in every runtime, you can use is instead of ==:
if type(x) is type(y):
fight()
if obj1==obj2:
pass
else:
#do som

Python automatic class assignment

In python. when I write x = 5, x becomes an instance of int automatically. But suppose I have defined a new class say number and I want x to become an instance of number instead of int when I assign it the value 5. Is this possible?
ie, Instead of this -->
>>> x = 5
>>> type(x)
<type 'int'>
Is this possible:
>>> x = 5
>>> type(x)
<type 'number'>
No. You would have to write a monkey patch to achieve this, that is incredibly unpythonic, can you simply not write
x = number(5)
:)
Note that you really should never do something like this. Jakob has the right answer, i.e. use x = number(5).
However, that said, I wanted to try how it could be done in theory, and here's one solution in the form of a decorator:
import types
class number(object):
def __init__(self, value):
self.value = value
def replace_int(x):
if isinstance(x, int):
return number(x)
else:
return x
def custom_numbers(f):
code = f.func_code
consts = tuple(map(replace_int, code.co_consts))
new_code = types.CodeType(code.co_argcount, code.co_nlocals,
code.co_stacksize, code.co_flags,
code.co_code, consts, code.co_names,
code.co_varnames, code.co_filename,
code.co_name, code.co_firstlineno,
code.co_lnotab)
return types.FunctionType(new_code, f.func_globals, f.func_name)
Any function you decorate, will end up using your custom number class:
#custom_numbers
def test():
x = 5
print type(x)
>>> test()
<class '__main__.number'>
The decorator works by replacing integer constants from the function's code-object with instances of the custom class. However, since function.co_code and code.co_consts are both read-only attributes, we have to create new code and function objects with the altered values.
One caveat is, that the values are assumed to be constants, so new instances are not created for each invocation of the function. If you mutate the value, that new value will be reflected in each subsequent call of the function.
You would have to take advantage of Python's language services to compile the statement and then walk the AST replacing the objects as appropriate.
In fact, 5 is an instance of int, x is just pointing to it. All variables in Python are references to objects. Thus, when you write type(x) you get the type of the object which x holds a reference to, in this case it is int.
If you assign another value to x, say x = "string", x will hold a reference to that string object, and type(x) will return <type 'str'>.

Categories