Create an object without calling a class
In Python you can add members dynamically to an object, but (1) the name must already exist (it must have been assigned) and (2) it must be bound to an instance of some class. To do so you may create an empty class:
class Empty:
pass # empty statement otherwise the class declaration cannot succeed
construct an instance of it and assign it to your variable
person = Empty()
and then add whatever data you want
person.name = 'Mike'
person.age = 25
person.gender = 'male'
On the other hand, if you don't need the additional features a "normal" class provides and you just want to store some data in a key=>value fashion you should probably just use a dictionary.
person={}
person['name']='Mike'
person['age']=25
person['gender']='male'
(notice that, at least up to Python 2.7, this is mostly just a stylistic/syntactic difference, since instance members are implemented underneath in terms of dictionaries)
As a general guideline, you want classes when you are instantiating multiple objects made in the same way (and where typically the assignment to the members is done in the class constructor; adding members later generally makes for difficult to follow code), dictionaries otherwise.
Python 3.3 Added SimpleNamespace class
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.
SimpleNamespace may be useful as a replacement for class NS: pass. However, for a structured record type use namedtuple() instead.
Here is an example on how you can use it:
from types import SimpleNamespace
person = SimpleNamespace(name='Mike', age=25, gender='male')
print(person)
Output:
namespace(age=25, gender='male', name='Mike')
from types import SimpleNamespace
person = SimpleNamespace()
person.name = 'Mike'
person.age = 25
person.gender = 'male'
print(person)
Output:
namespace(age=25, gender='male', name='Mike')
In Python, person
has to be an instance of some class; it can't just materialize out of thin air.
You could achieve something similar to your code like so:
class Struct(object): pass
person = Struct()
person.name = 'Mike'
person.age = 25
person.gender = 'male'
print(person.__dict__)
This prints:
{'gender': 'male', 'age': 25, 'name': 'Mike'}
Python won't magically create a container object when you start assigning attributes to it, and if matlab allows this, I'd consider matlab badly broken. Consider this:
person.name = "Mike"
persom.age = 25
person.sex = "Male"
Now we have two objects, person
and persom
, and person
doesn't have age
, and there was no hint that this happened. Later you try to print person.age
and, one would hope, matlab then complains... two pages after the actual mistake.
A class can itself be used as a container or namespace. There's no need to instantiate it, and it'll save you a bit of typing if you just want a bundle of attributes.
class sex:
male = "M"
female = "F"
class person:
name = "Mike"
age = 25
sex = sex.male
To access or modify any of these, you can use person.name
, etc.
N.B. I used a class for sex
as well to illustrate one of the benefits of doing so: it provides consistency in data values (no remembering whether you used "M" or "Male" or "male") and catches typos (i.e. Python will complain about sex.mlae but not about the string "mlae" and if you were later checking it against "male" the latter would fail).
Of course, you still run the risk of misspelling name
, age
, or sex
in this type of class definition. So what you can do is use the class as a template and instantiate it.
class Person:
def __init__(self, name, age=None, sex=None):
self.name, self.age, self.sex = name, age, sex
Now when you do:
person = Person("Mike", 25, sex.male)
or if you want to document what all those parameters are:
person = Person("Mike", age=25, sex=sex.male)
it is pretty much impossible to end up with an object that has a misspelled attribute name. If you mess it up, Python will give you an error message at the point you made the mistake. That's just one reason to do it this way.