I used setattr method to set column names from an Excel file as attribute of object. However, these names include spaces like "Vendor name". How can I access the attribute like this?
for k in self.df.columns.values.tolist():
setattr(self,k,self.df[k])
With getattr, of course:
>>> class MyClass: pass
...
>>> my_object = MyClass()
>>> setattr(my_object, 'spaces are considered harmful', 42)
>>> getattr(my_object, 'spaces are considered harmful')
42
Or, you can always access the namespace of a custom class (where you haven't defined __slots__) by using the namespace directly:
>>> vars(my_object) is my_object.__dict__
True
>>> vars(my_object)
{'spaces are considered harmful': 42}
>>> my_object.__dict__
{'spaces are considered harmful': 42}
>>> vars(my_object)['spaces are considered harmful']
42
>>> my_object.__dict__['spaces are considered harmful']
42
Although really, instead of a custom class, it sounds like you want some container that is a sort of mapping from strings to other objects.
Related
I would like to create a dictionary which based on a string keyword returns a subclass of Foo which I can later instantiate. Is this possible or is it an incorrect approach to the problem?
Pseudo code:
subclasses_of_foo = {"foo1": Foo1, "foo2": Foo2}
subclass_of_foo = subclasses_of_foo["foo1"]
instance = subclass_of_foo()
Sure, you can do that. Give it a go.
Your approach is entirely correct and works. Classes are just objects, just like everything else in Python. They can be stored as values in a dictionary.
Demo:
>>> class Foo:
... pass
...
>>> class Bar:
... pass
...
>>> classmap = {'foo': Foo, 'bar': Bar}
>>> classmap['foo']
<class __main__.Foo at 0x107eee1f0>
>>> classmap['foo']()
<__main__.Foo instance at 0x107eefcb0>
Note that duck typing is something else entirely; it is the practice of treating any object as the correct type provided it implements the attributes and methods you expected (if it walks like a duck, it is a duck).
Suppose o is a Python object, and I want all of the fields of o, without any methods or __stuff__. How can this be done?
I've tried things like:
[f for f in dir(o) if not callable(f)]
[f for f in dir(o) if not inspect.ismethod(f)]
but these return the same as dir(o), presumably because dir gives a list of strings. Also, things like __class__ would be returned here, even if I get this to work.
You can get it via the __dict__ attribute, or the built-in vars function, which is just a shortcut:
>>> class A(object):
... foobar = 42
... def __init__(self):
... self.foo = 'baz'
... self.bar = 3
... def method(self, arg):
... return True
...
>>> a = A()
>>> a.__dict__
{'foo': 'baz', 'bar': 3}
>>> vars(a)
{'foo': 'baz', 'bar': 3}
There's only attributes of the object. Methods and class attributes aren't present.
You could use the built-in method vars()
The basic answer is "you can't do so reliably". See this question.
You can get an approximation with [attr for attr in dir(obj) if attr[:2] + attr[-2:] != '____' and not callable(getattr(obj,attr))].
However, you shouldn't rely on this, because:
Because dir() is supplied primarily as a convenience for use at an interactive prompt, it tries to supply an interesting set of names more than it tries to supply a rigorously or consistently defined set of names, and its detailed behavior may change across releases.
In other words, there is no canonical way to get a list of "all of an object's attributes" (or "all of an object's methods").
If you're doing some kind of dynamic programming that requires you to iterate over unknwon fields of an object, the only reliable way to do it is to implement your own way of keeping track of those fields. For instance, you could use an attribute naming convention, or a special "fields" object, or, most simply, a dictionary.
This should work for callables:
[f for f in dir(o) if not callable(getattr(o,f))]
You could get rid of the rest with:
[f for f in dir(o) if not callable(getattr(o,f)) and not f.startswith('__')]
You can iterate through an instance's __dict__ attribute and look for non-method things.
For example:
CALLABLES = types.FunctionType, types.MethodType
for key, value in A().__dict__.items():
if not isinstance(value, CALLABLES):
print(key)
Output:
foo
bar
You can do it in a single statement with a list comprehension:
print([key for key, value in A.__dict__.items() if not isinstance(value, CALLABLES)])
Which would print ['foo', 'bar'].
You can get it via fields attribute: o._fields_
I was reading the python descriptors and there was one line there
Python first looks for the member in the instance dictionary. If it's
not found, it looks for it in the class dictionary.
I am really confused what is instance dict and what is class dictionary
Can anyone please explain me with code what is that
I was thinking of them as same
An instance dict holds a reference to all objects and values assigned to the instance, and the class level dict holds all references at the class namespace.
Take the following example:
>>> class A(object):
... def foo(self, bar):
... self.zoo = bar
...
>>> i = A()
>>> i.__dict__ # instance dict is empty
{}
>>> i.foo('hello') # assign a value to an instance
>>> i.__dict__
{'zoo': 'hello'} # this is the instance level dict
>>> i.z = {'another':'dict'}
>>> i.__dict__
{'z': {'another': 'dict'}, 'zoo': 'hello'} # all at instance level
>>> A.__dict__.keys() # at the CLASS level, only holds items in the class's namespace
['__dict__', '__module__', 'foo', '__weakref__', '__doc__']
I think, you can understand with this example.
class Demo(object):
class_dict = {} # Class dict, common for all instances
def __init__(self, d):
self.instance_dict = d # Instance dict, different for each instance
And it's always possible to add instance attribute on the fly like this: -
demo = Demo({1: "demo"})
demo.new_dict = {} # A new instance dictionary defined just for this instance
demo2 = Demo({2: "demo2"}) # This instance only has one instance dictionary defined in `init` method
So, in the above example, demo instance has now 2 instance dictionary - one added outside the class, and one that is added to each instance in __init__ method. Whereas, demo2 instance has just 1 instance dictionary, the one added in __init__ method.
Apart from that, both the instances have a common dictionary - the class dictionary.
Those dicts are the internal way of representing the object or class-wide namespaces.
Suppose we have a class:
class C(object):
def f(self):
print "Hello!"
c = C()
At this point, f is a method defined in the class dict (f in C.__dict__, and C.f is an unbound method in terms of Python 2.7).
c.f() will make the following steps:
look for f in c.__dict__ and fail
look for f in C.__dict__ and succeed
call C.f(c)
Now, let's do a trick:
def f_french():
print "Bonjour!"
c.f = f_french
We've just modified the object's own dict. That means, c.f() will now print Bounjour!. This does not affect the original class behaviour, so that other C's instances will still speak English.
Class dict is shared among all the instances (objects) of the class, while each instance (object) has its own separate copy of instance dict.
You can define attributes separately on a per instance basis rather than for the whole class
For eg.
class A(object):
an_attr = 0
a1 = A()
a2 = A()
a1.another_attr = 1
Now a2 will not have another_attr. That is part of the instance dict rather than the class dict.
Rohit Jain has the simplest python code to explain this quickly. However, understanding the same ideas in Java can be useful, and there is much more information about class and instance variables here
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"
What's the easiest way to create a naked object that I can assign attributes to?
The specific use case is: I'm doing various operations on a Django object instance, but sometimes the instance is None (there is on instance). In this case I'd like to create the simplest possible fake object such that I can assign values to its attributes (eg. myobject.foo = 'bar').
Basically I'm looking for the Python equivalent of this piece of Javascript:
myobject = {}
myobject.foo = 'bar'
I know I can use a mock object/library for this, but I'm hoping for a very simple solution (as simple as the Javascript above). Is there a way to create a naked object instance? Something like:
myobject = object()
myobject.foo = 'bar'
You need to create a simple class first:
class Foo(object):
pass
myobject = Foo()
myobject.foo = 'bar'
You can make it a one-liner like this:
myobject = type("Foo", (object,), {})()
myobject.foo = 'bar'
The call to type functions identically to the previous class statement.
If you want to be really minimal...
myobject = type("", (), {})()
The key is that the built-in types (such as list and object) don't support user-defined attributes, so you need to create a type using either a class statement or a call to the 3-parameter version of type.
If you're using Python >= 3.3 you could always use SimpleNamespace; which is included in the Python types module.
SimpleNamespace is great because you also get a repr and equivalency testing for free; both of which might come in handy even for a minimalist object.
Translating the JavaScript in the OP’s question would look like:
from types import SimpleNamespace
myobject = SimpleNamespace() # myobject = {}
myobject.foo = 'bar'
You can also use keyword arguments when instantiating SimpleNamespace. These arguments will become attributes on the instantiated SimpleNamespace:
p = SimpleNamespace(name='gary')
p.age = 32
p # => namespace(age=32, name='gary')
So a quick and easy way to turn a dictionary into a SimpleNamespace object —provided the dictionary keys are proper identifiers— is as simple as:
d = {
'name': 'gary',
'age': 33 # had a birthday.
}
p = SimpleNamespace(**d)
Python >= 3.7 has dataclasses which are basically “mutable named tuples”. This could be something you may want to use if you have a lot of data objects.
Use the Bunch module:
sudo pip install bunch
A bunch is a dictionary that allows to access its content via the dict.key syntax.
And then like that:
from bunch import Bunch
b = Bunch()
b.foo = "Bar"
b["foo2"] = "Bar2"
print b
>> Bunch(foo='Bar', foo2='Bar2')
b["foo"] = "Baz"
print b
>> Bunch(foo='Baz', foo2='Bar2')
I'm coming here very late, but I'm surprised nobody has mentioned namedtuples, which accomplish this kind of thing:
Foo = namedtuple('Foo', ['x'])
f = Foo(x='myattribute')
f.x
For Python 3,
class Obj: pass
o = Obj()
o.name = 'gary'
o.age = 32
o
# <__main__.Obj at 0x17235ca65c0>
o.__dict__
# {'name': 'gary', 'age': 32}
class NakedObject(object):
pass
myobject = NakedObject()
myobject.foo = 'bar'
Functions can have attributes in Python 3. Compared to a naked class, you can save one whole line of code.
naked = lambda: None
naked.foo = 'bar'
You would need to subclass object first like this...
class Myobject(object):
pass
myobject1 = Myobject()
myobject1.foo = 'bar'
Perhaps you are looking for something like this:
myobject={}
myobject['foo']='bar'
then it can be called like:
print myobject['foo']
or you could use a class object for this:
class holder(object):
pass
then you can use something like this:
hold=holder()
hold.myobject='bar'
print hold.myobject
You should probably just use a dict, as per #PsychicOak's answer.
However, if you really want an object you can manipulate, try:
class FooClass(object): pass
You can then assign attributes on FooClass itself, or on instances, as you wish.
I usually prefer to create a null object for my class:
class User(Model):
username = CharField()
password = CharField()
NONE_USER = User(username='', password='')
Then I use it where I would use your naked object.
In some cases extending a dict can help you
like:
class SpecificModelData(dict):
pass
...
class Payload(dict):
... enter code here
why a dict? it works nicely together with serializers.
Why new class? - it gives you a name and a new type