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
Related
I came across a method in Python that returns a class, but can be destructured as if it's a tuple.
How can you define a result of a function to be both an instance of a class AND use destructure assignment as if it's a tuple?
An example where you see this behavior:
import scipy.stats as stats
res = stats.ttest_ind(data1, data2)
print(type(res)) # <class 'scipy.stats.stats.Ttest_indResult'>
# One way to assign values is by directly accessing the instance's properties.
p = res.pvalue
t = res.statistic
# A second way is to treat the result as a tuple, and assign to variables directly. But how is this working?
# We saw above that the type of the result is NOT a tuple but a class. How would Python know the order of the properties here? (It's not like we're destructuring based on named properties)
t, p = stats.ttest_ind(data1, data2)
It's a named tuple, which is basically an extension to tuple type in python.
To unpack a data type with a, b = some_object, the object on the right side needs to be iterable. A list or tuple works, obviously, but you can make your own class iterable by implementing an __iter__ method.
For example, the following class would behave consistently with the interface you've shown the Ttest_indResult class to have (though it's probably implemented very differently):
class MyClass:
def __init__(self, statistic, pvalue):
self.statistic = statistic # these attributes are accessible by name
self.pvalue = pvalue
def __iter__(self): # but you can also iterate to get the same values
yield self.statistic
yield self.pvalue
If I had a dict object say values = {'a': 'alpha', 'b': 'bravo'}.
I've seen use cases where one may do values['a'] to get the value of the a key.
Now I am aware this is a normal way to access dict values, but I have also seen it used with objects such as a Tk.Scrollbar['command'] = yadayada.
Is there a name or documentation for this practice of using [ ] with objects?
The [ ] is called indexing or slicing (or sometimes array/sequence/mapping-like access). The x[idx] = val is called index or slice assigment.
The methods that are responsible how the instance acts when indexed or sliced are:
__getitem__,
__setitem__ and
__delitem__.
(In Python-2.x there is also __getslice__, ... but these are deprecated since python 2.0 - if you don't inherit from a class that uses these you shouldn't need those)
For example (missing any actual implementation, just some prints):
class Something(object):
def __getitem__(self, item):
print('in getitem')
def __setitem__(self, item, newvalue):
print('in setitem')
def __delitem__(self, item):
print('in delitem')
For example:
>>> sth = Something()
>>> sth[10]
in getitem
>>> sth[10] = 100
in setitem
>>> del sth[10]
in delitem
This is briefly described in the python tkinter documentation. Tkinter does it simply as a convenience, the feature has no name that is specific to tkinter.
https://docs.python.org/3.6/library/tkinter.html#setting-options
Options control things like the color and border width of a widget. Options can be set in three ways:
At object creation time, using keyword arguments
fred = Button(self, fg="red", bg="blue")
After object creation, treating the option name like a dictionary index
fred["fg"] = "red"
fred["bg"] = "blue"
Use the config() method to update multiple attrs subsequent to object creation
fred.config(fg="red", bg="blue")
For more general purpose information outside of the context of tkinter, see A python class that acts like dict
I'm quite new in Python. I suppose my question is simple, but I don't find any answer. I would like to create, delete a composed list (as a C struct) and access items inside:
for i in list1
create item in list2[list3[StringVar1, StringVar2], bool1, Frame1]
item.list3[StringVar1] = i
item.list3[StringVar2] = value
item.bool1 = True
item.Frame1 = tk.Frame(self)
How can I write that in Python?
Edit: Martijn Pieters is right, I've just corrected.
I don't exactly understand by what you mean when you say composed list, but indeed you can have a struct in Python.
Ideally, you mean that you want an immutable C-Struct like object then, you can create it quite easily. In Python its called a namedtuple, or atleast this is the closest that I have come across. You can of course create your own generic object in Python, and add arguments, but that would be a dynamic struct instead.
Ideally, in C, you would have a struct like this ->
struct tag_name
{
type attribute;
type attribute2;
/* ... */
};
And you could access the attributes of the struct like so tag_name.attribute. So, this is how a namedtuple works:
>>> from collections import namedtuple
>>> NetworkAddress = namedtuple('NetworkAddress',['hostname','port'])
>>> a = NetworkAddress('www.python.org',80)
>>> a.hostname
'www.python.org'
>>> a.port
80
>>> host, port = a
>>> len(a)
2
>>> type(a)
<class '_ _main_ _.NetworkAddress'>
>>> isinstance(a, tuple)
True
>>>
If there is anything that you would like in specific, then please update your question to explain composed list so that I can update this answer.
However, this is typical of a statically typed language like C, since we're using Python, we can use some cool dynamic properties, so you an essentially create an object that you can add properties to as you see fit:
class DynamicObject(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
Console session
>>> class DynamicObject(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
>>> happy_obj = DynamicObject(name="Happy Gilmore")
>>> happy_obj.name
'Happy Gilmore'
Credits ->
https://stackoverflow.com/users/320726/6502 for the dynamic object code. Thanks man :)
You can always use a Python dictionary
item = {}
item["list2"] = {}
item["list2"]["list3"] = {}
item["list2"]["list3"][Var1] = Value1
item["list2"]["list3"][Var2] = Value2
...
You can assign another dictionary or a list as a value as well.
As far as delete is concerned you can use the "del" keyword to delete. For ex
dictionary = {}
dictionary["name"] = {}
dictionary["name1"] = {}
del dictionary["name1"]
dictionary
{'name': {}}
You should know that new style objects (anything derived from object) have a __dict__ member, which is a dict. So you can do:
class X(object):
pass
x = X()
x.__dict__["a"] = 1
x.a #1
another way to do this is to user setattr and getattr:
setattr(x, "b", 2) # same as x.__dict__["b"] = 2
You can use this to build named access to some input structure, however you will need names and values in your compound input structure (essentially, something like nested dicts for all nodes that are to have named children)
However, I think your data struct is wrong. For the use method is like array like in c. That means we can find elem by the number index, so you can't use list like list3[StringVar1,StringVar2].
Maybe the dictionary in python can meet your need. If you want to use item.list3 you must define a class in python.
In python how can we create a new object without having a predefined Class and later dynamically add properties to it ?
example:
dynamic_object = Dynamic()
dynamic_object.dynamic_property_a = "abc"
dynamic_object.dynamic_property_b = "abcdefg"
What is the best way to do it?
EDIT Because many people advised in comments that I might not need this.
The thing is that I have a function that serializes an object's properties. For that reason, I don't want to create an object of the expected class due to some constructor restrictions, but instead create a similar one, let's say like a mock, add any "custom" properties I need, then feed it back to the function.
Just define your own class to do it:
class Expando(object):
pass
ex = Expando()
ex.foo = 17
ex.bar = "Hello"
If you take metaclassing approach from #Martijn's answer, #Ned's answer can be rewritten shorter (though it's obviously less readable, but does the same thing).
obj = type('Expando', (object,), {})()
obj.foo = 71
obj.bar = 'World'
Or just, which does the same as above using dict argument:
obj = type('Expando', (object,), {'foo': 71, 'bar': 'World'})()
For Python 3, passing object to bases argument is not necessary (see type documentation).
But for simple cases instantiation doesn't have any benefit, so is okay to do:
ns = type('Expando', (object,), {'foo': 71, 'bar': 'World'})
At the same time, personally I prefer a plain class (i.e. without instantiation) for ad-hoc test configuration cases as simplest and readable:
class ns:
foo = 71
bar = 'World'
Update
In Python 3.3+ there is exactly what OP asks for, types.SimpleNamespace. It's just:
A simple object subclass that provides attribute access to its namespace, as well as a meaningful repr.
Unlike object, with SimpleNamespace you can add and remove attributes. If a SimpleNamespace object is initialized with keyword arguments, those are directly added to the underlying namespace.
import types
obj = types.SimpleNamespace()
obj.a = 123
print(obj.a) # 123
print(repr(obj)) # namespace(a=123)
However, in stdlib of both Python 2 and Python 3 there's argparse.Namespace, which has the same purpose:
Simple object for storing attributes.
Implements equality by attribute names and values, and provides a simple string representation.
import argparse
obj = argparse.Namespace()
obj.a = 123
print(obj.a) # 123
print(repr(obj)) # Namespace(a=123)
Note that both can be initialised with keyword arguments:
types.SimpleNamespace(a = 'foo',b = 123)
argparse.Namespace(a = 'foo',b = 123)
Using an object just to hold values isn't the most Pythonic style of programming. It's common in programming languages that don't have good associative containers, but in Python, you can use use a dictionary:
my_dict = {} # empty dict instance
my_dict["foo"] = "bar"
my_dict["num"] = 42
You can also use a "dictionary literal" to define the dictionary's contents all at once:
my_dict = {"foo":"bar", "num":42}
Or, if your keys are all legal identifiers (and they will be, if you were planning on them being attribute names), you can use the dict constructor with keyword arguments as key-value pairs:
my_dict = dict(foo="bar", num=42) # note, no quotation marks needed around keys
Filling out a dictionary is in fact what Python is doing behind the scenes when you do use an object, such as in Ned Batchelder's answer. The attributes of his ex object get stored in a dictionary, ex.__dict__, which should end up being equal to an equivalent dict created directly.
Unless attribute syntax (e.g. ex.foo) is absolutely necessary, you may as well skip the object entirely and use a dictionary directly.
Use the collections.namedtuple() class factory to create a custom class for your return value:
from collections import namedtuple
return namedtuple('Expando', ('dynamic_property_a', 'dynamic_property_b'))('abc', 'abcdefg')
The returned value can be used both as a tuple and by attribute access:
print retval[0] # prints 'abc'
print retval.dynamic_property_b # prints 'abcdefg'
One way that I found is also by creating a lambda. It can have sideeffects and comes with some properties that are not wanted. Just posting for the interest.
dynamic_object = lambda:expando
dynamic_object.dynamic_property_a = "abc"
dynamic_object.dynamic_property_b = "abcdefg"
I define a dictionary first because it's easy to define. Then I use namedtuple to convert it to an object:
from collections import namedtuple
def dict_to_obj(dict):
return namedtuple("ObjectName", dict.keys())(*dict.values())
my_dict = {
'name': 'The mighty object',
'description': 'Yep! Thats me',
'prop3': 1234
}
my_obj = dict_to_obj(my_dict)
Ned Batchelder's answer is the best. I just wanted to record a slightly different answer here, which avoids the use of the class keyword (in case that's useful for instructive reasons, demonstration of closure, etc.)
Just define your own class to do it:
def Expando():
def inst():
None
return inst
ex = Expando()
ex.foo = 17
ex.bar = "Hello"
I have a class, and I would like to be able to create multiple objects of that class and place them in an array. I did it like so:
rooms = []
rooms.append(Object1())
...
rooms.append(Object4())
I then have a dict of functions, and I would like to pass the object to the function. However, I'm encountering some problems..For example, I have a dict:
dict = {'look': CallLook(rooms[i])}
I'm able to pass it into the function, however; in the function if I try to call an objects method it gives me problems
def CallLook(current_room)
current_room.examine()
I'm sure that there has to be a better way to do what I'm trying to do, but I'm new to Python and I haven't seen a clean example on how to do this. Anyone have a good way to implement a list of objects to be passed into functions? All of the objects contain the examine method, but they are objects of different classes. (I'm sorry I didn't say so earlier)
The specific error states: TypeError: 'NoneType' object is not callable
Anyone have a good way to implement a list of objects to be passed into functions? All of the objects contain the examine method, but they are objects of different classes. (I'm sorry I didn't say so earlier)
This is Python's plain duck-typing.
class Room:
def __init__(self, name):
self.name = name
def examine(self):
return "This %s looks clean!" % self.name
class Furniture:
def __init__(self, name):
self.name = name
def examine(self):
return "This %s looks comfortable..." % self.name
def examination(l):
for item in l:
print item.examine()
list_of_objects = [ Room("Living Room"), Furniture("Couch"),
Room("Restrooms"), Furniture("Bed") ]
examination(list_of_objects)
Prints:
This Living Room looks clean!
This Couch looks comfortable...
This Restrooms looks clean!
This Bed looks comfortable...
As for your specific problem: probably you have forgotten to return a value from examine()? (Please post the full error message (including full backtrace).)
I then have a dict of functions, and I would like to pass the object to the function. However, I'm encountering some problems..For example, I have a dict:
my_dict = {'look': CallLook(rooms[i])} # this is no dict of functions
The dict you have created may evaluate to {'look': None} (assuming your examine() doesn't return a value.) Which could explain the error you've observed.
If you wanted a dict of functions you needed to put in a callable, not an actual function call, e.g. like this:
my_dict = {'look': CallLook} # this is a dict of functions
if you want to bind the 'look' to a specific room you could redefine CallLook:
def CallLook(current_room)
return current_room.examine # return the bound examine
my_dict = {'look': CallLook(room[i])} # this is also a dict of functions
Another issue with your code is that you are shadowing the built-in dict() method by naming your local dictionary dict. You shouldn't do this. This yields nasty errors.
Assuming you don't have basic problems (like syntax errors because the code you have pasted is not valid Python), this example shows you how to do what you want:
>>> class Foo():
... def hello(self):
... return 'hello'
...
>>> r = [Foo(),Foo(),Foo()]
>>> def call_method(obj):
... return obj.hello()
...
>>> call_method(r[1])
'hello'
Assuming you have a class Room the usual way to create a list of instances would be using a list comprehension like this
rooms = [Room() for i in range(num_rooms)]
I think there are some things you may not be getting about this:
dict = {'look': CallLook(rooms[i])}
This creates a dict with just one entry: a key 'look', and a value which is the result of evaluating CallLook(rooms[i]) right at the point of that statement. It also then uses the name dict to store this object, so you can no longer use dict as a constructor in that context.
Now, the error you are getting tells us that rooms[i] is None at that point in the programme.
You don't need CallLook (which is also named non-standardly) - you can just use the expression rooms[i].examine(), or if you want to evaluate the call later rooms[i].examine.
You probably don't need the dict at all.
That is not a must, but in some cases, using hasattr() is good... getattr() is another way to get an attribute off an object...
So:
rooms = [Obj1(),Obj2(),Obj3()]
if hasattr(rooms[i], 'examine'):#First check if our object has selected function or attribute...
getattr(rooms[i], 'examine') #that will just evaluate the function do not call it, and equals to Obj1().examine
getattr(rooms[i], 'examine')() # By adding () to the end of getattr function, we evalute and then call the function...
You may also pass parameters to examine function like:
getattr(rooms[i], 'examine')(param1, param2)
I'm not sure of your requirement, but you can use dict to store multiple object of a class.
May be this will help,
>>> class c1():
... print "hi"
...
hi
>>> c = c1()
>>> c
<__main__.c1 instance at 0x032165F8>
>>> d ={}
>>> for i in range (10):
... d[i] = c1()
...
>>> d[0]
<__main__.c1 instance at 0x032166E8>
>>> d[1]
<__main__.c1 instance at 0x032164B8>
>>>
It will create a object of c1 class and store it in dict. Obviously, in this case you can use list instead of dict.