Does there exist empty class in python? - python

Does there exist special class in python to create empty objects? I tried object(), but it didn't allow me to add fields.
I want to use it like this:
obj = EmptyObject()
obj.foo = 'far'
obj.bar = 'boo'
Should I each time(in several independent scripts) define new class like this?
class EmptyObject:
pass
I use python2.7

types.SimpleNamespace was introduced with Python 3.3 to serve this exact purpose. The documentation also shows a simple way to implement it yourself in Python, so you can add it to your pre-Python 3.3 setup and use it as if it was there (note that the actual implementation is done in C):
class SimpleNamespace (object):
def __init__ (self, **kwargs):
self.__dict__.update(kwargs)
def __repr__ (self):
keys = sorted(self.__dict__)
items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
return "{}({})".format(type(self).__name__, ", ".join(items))
def __eq__ (self, other):
return self.__dict__ == other.__dict__
But of course, if you don’t need its few features, a simple class Empty: pass does just the same.

If you are looking for a place holder object to which you can add arbitrary static members, then the closest I got is an empty lambda function.
obj = lambda: None # Dummy function
obj.foo = 'far'
obj.bar = 'boo'
print obj.foo, obj.bar
# far boo
Remember: obj is not an object of a class, object doesn't mean class instance, because in Python classes and functions are objects at runtime just like class instances

There is no types.SimpleNamespace in Python 2.7, you could use collections.namedtuple() for immutable objects instead:
>>> from collections import namedtuple
>>> FooBar = namedtuple('FooBar', 'foo bar')
>>> FooBar('bar', 'foo')
FooBar(foo='bar', bar='foo')
Or argparse.Namespace:
>>> from argparse import Namespace
>>> o = Namespace(foo='bar')
>>> o.bar = 'foo'
>>> o
Namespace(bar='foo', foo='bar')
See also, How can I create an object and add attributes to it?

You can create a new type dynamically with the fields you want it to have using the type function, like this:
x = type('empty', (object,), {'foo': 'bar'})
x.bar = 3
print(x.foo)
This is not entirely what you want though, since it will have a custom type, not an empty type.

Related

Creating anonymous objects in Python [duplicate]

I'm debugging some Python that takes, as input, a list of objects, each with some attributes.
I'd like to hard-code some test values -- let's say, a list of four objects whose "foo" attribute is set to some number.
Is there a more concise way than this?
x1.foo = 1
x2.foo = 2
x3.foo = 3
x4.foo = 4
myfunc([x1, x2, x3, x4])
Ideally, I'd just like to be able to say something like:
myfunc([<foo=1>, <foo=2>, <foo=3>, <foo=4>])
(Obviously, that is made-up syntax. But is there something similar that really works?)
Note: This will never be checked in. It's just some throwaway debug code. So don't worry about readability or maintainability.
I found this: http://www.hydrogen18.com/blog/python-anonymous-objects.html, and in my limited testing it seems like it works:
>>> obj = type('',(object,),{"foo": 1})()
>>> obj.foo
1
I like Tetha's solution, but it's unnecessarily complex.
Here's something simpler:
>>> class MicroMock(object):
... def __init__(self, **kwargs):
... self.__dict__.update(kwargs)
...
>>> def print_foo(x):
... print x.foo
...
>>> print_foo(MicroMock(foo=3))
3
Wow, so brief, such Python! O.o
>>> Object = lambda **kwargs: type("Object", (), kwargs)
Then you can use Object as a generic object constructor:
>>> person = Object(name = "Bernhard", gender = "male", age = 42)
>>> person.name
'Bernhard'
>>>
Now technically this creates a class object, not an object object. But you can treat it like an anonymous object or you modify the first line by appending a pair of parenthesis to create an immediate instance:
>>> Object = lambda **kwargs: type("Object", (), kwargs)()
Have a look at this:
class MiniMock(object):
def __new__(cls, **attrs):
result = object.__new__(cls)
result.__dict__ = attrs
return result
def print_foo(x):
print x.foo
print_foo(MiniMock(foo=3))
Maybe you can use namedtuple to solve this as following:
from collections import namedtuple
Mock = namedtuple('Mock', ['foo'])
mock = Mock(foo=1)
mock.foo // 1
Another obvious hack:
class foo1: x=3; y='y'
class foo2: y=5; x=6
print(foo1.x, foo2.y)
But for your exact usecase, calling a function with anonymous objects directly, I don't know any one-liner less verbose than
myfunc(type('', (object,), {'foo': 3},), type('', (object,), {'foo': 4}))
Ugly, does the job, but not really.
As of Python 3.3, there's types.SimpleNamespace that does exactly what you want:
myfunc([types.SimpleNamespace(foo=1), types.SimpleNamespace(foo=2), types.SimpleNamespace(foo=3), types.SimpleNamespace(foo=4)])
That's a tad wordy, but you can clean it up with an alias:
_ = types.SimpleNamespace
myfunc([_(foo=1), _(foo=2), _(foo=3), _(foo=4)])
And now that's actually pretty close to the fictional syntax in your question.
anonymous_object = type('',(),{'name':'woody', 'age':'25'})()
anonymous_object.name
> 'woody'
There is a cool way but hard to understand.
It use type() create a no-named class with default init params,
then init it without any param and get the anonymous object.
I will use lambda
obj = lambda: None
obj.s = 'abb'
obj.i = 122
Non classy:
def mock(**attrs):
r = lambda:0
r.__dict__ = attrs
return r
def test(a, b, c, d):
print a.foo, b.foo, c.foo, d.foo
test(*[mock(foo=i) for i in xrange(1,5)])
# or
test(mock(foo=1), mock(foo=2), mock(foo=3), mock(foo=4))
>>> from unittest.mock import Mock
>>> obj = Mock(foo=1)
>>> obj.foo
1
I was surprised to not find this in the answers already.
myfunc([Mock(foo=1), Mock(foo=2), Mock(foo=3), Mock(foo=4)])
I think it's the most straight-forward and "canonical" way to create a dummy/anonymous object in Python. It works since Python 3.3 (2012).
This is how I did it:
from mock import patch
import requests
class MockResponse:
def __init__(self, text, status_code):
self.text = text
self.status_code = status_code
class TestSomething(unittest.TestCase):
#patch('requests.get',return_value=MockResponse('the result',200))
def test_some_request(self, *args, **kwargs):
response = requests.get('some.url.com')
assert response.text=='the result'
assert response.status_code=='200'
If you are using Python 3.7 or above, you can use named tuples to enhance the created object with immutability, docstring, and handy tuple methods:
from collections import namedtuple
PyObj = lambda **kwargs: namedtuple('PyObj', kwargs.keys())._make(kwargs.values())
o = PyObj(foo = 1)
print(o)
# prints: PyObj(foo=1)
o.foo
# returns: 1
o.foo = 0
# exception:
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# AttributeError: can't set attribute
print(PyObj(foo = 1, bar = 'baz'))
# prints: PyObj(foo=1, bar='baz')
Python 3.7+ is required to ensure keys and values are in the same order.
However, if the list of attributes is predefined, you can use namedtuple directly, as Huachao suggested, there's no need to define the PyObj function and you can use it in v2.7.
from collections import namedtuple
foo = namedtuple('Foo', 'foo')
myfunc = lambda l: [x.foo * 10 for x in l]
myfunc([foo(1), foo(2), foo(3), foo(4)])
# returns [10, 20, 30, 40]
Plus, it looks more like the syntax you are looking for.
Yes, I very much missed the straightforward anonymous objects in JavaScript, particularly in function return values, where you can just say
function george() {
return {fred:6, jim:9};
}
x = george();
y = x.fred;
You can use a dictionary to get the same effect, but all those square brackets and single quotes look muddly. So I now do the following, which works:
def fred():
class rv:
x=0
rv.y = 6
return rv
def jim():
class rv:
x=0
rv.y = 9
return rv
a = fred()
b = jim()
print(a.y, b.y, id(a.y), id(b.y))
It would feel nicer to have a global class RV, and instantiate it to get the same effect, but this way the function has no external dependencies.

Create Class Implicitly In Python

I have a function that its job is generate a python class implicitly according to the given name that pass throw the function. After that I want to create field and method implicitly for the generated class too. I don't know how can start it. Can someone help...
Do you really need a class? For "types" created at runtime, maybe namedtuple would be a solution.
from collections import namedtuple
MyType= namedtuple("MyType", "field1 method1")
x = MyType(field1="3", method1=lambda x: x+1)
print x.field1, x.method1(3)
You can try something like this using type():
def my_func(self):
return 'my_func to become my_method!'
def class_maker(name,**kwargs):
return type(name, (object,), kwargs)
A = class_maker('MyClass',my_method=my_func, field='this is my_field!')
inst = A()
print inst.my_method()
print inst.field
print inst
print A
Outputs:
my_func to become my_method!
this is my_field!
<__main__.MyClass object at 0x962902c>
<class '__main__.MyClass'>

How do I get list of methods in a Python class?

I want to iterate through the methods in a class, or handle class or instance objects differently based on the methods present. How do I get a list of class methods?
Also see:
How can I list the methods in a
Python 2.5 module?
Looping over
a Python / IronPython Object
Methods
Finding the methods an
object has
How do I look inside
a Python object?
How Do I
Perform Introspection on an Object in
Python 2.x?
How to get a
complete list of object’s methods and
attributes?
Finding out which
functions are available from a class
instance in python?
An example (listing the methods of the optparse.OptionParser class):
>>> from optparse import OptionParser
>>> import inspect
#python2
>>> inspect.getmembers(OptionParser, predicate=inspect.ismethod)
[([('__init__', <unbound method OptionParser.__init__>),
...
('add_option', <unbound method OptionParser.add_option>),
('add_option_group', <unbound method OptionParser.add_option_group>),
('add_options', <unbound method OptionParser.add_options>),
('check_values', <unbound method OptionParser.check_values>),
('destroy', <unbound method OptionParser.destroy>),
('disable_interspersed_args',
<unbound method OptionParser.disable_interspersed_args>),
('enable_interspersed_args',
<unbound method OptionParser.enable_interspersed_args>),
('error', <unbound method OptionParser.error>),
('exit', <unbound method OptionParser.exit>),
('expand_prog_name', <unbound method OptionParser.expand_prog_name>),
...
]
# python3
>>> inspect.getmembers(OptionParser, predicate=inspect.isfunction)
...
Notice that getmembers returns a list of 2-tuples. The first item is the name of the member, the second item is the value.
You can also pass an instance to getmembers:
>>> parser = OptionParser()
>>> inspect.getmembers(parser, predicate=inspect.ismethod)
...
There is the dir(theobject) method to list all the fields and methods of your object (as a tuple) and the inspect module (as codeape write) to list the fields and methods with their doc (in """).
Because everything (even fields) might be called in Python, I'm not sure there is a built-in function to list only methods. You might want to try if the object you get through dir is callable or not.
Python 3.x answer without external libraries
method_list = [func for func in dir(Foo) if callable(getattr(Foo, func))]
dunder-excluded result:
method_list = [func for func in dir(Foo) if callable(getattr(Foo, func)) and not func.startswith("__")]
Say you want to know all methods associated with list class
Just Type The following
print (dir(list))
Above will give you all methods of list class
Try the property __dict__.
you can also import the FunctionType from types and test it with the class.__dict__:
from types import FunctionType
class Foo:
def bar(self): pass
def baz(self): pass
def methods(cls):
return [x for x, y in cls.__dict__.items() if type(y) == FunctionType]
methods(Foo) # ['bar', 'baz']
You can list all methods in a python class by using the following code
dir(className)
This will return a list of all the names of the methods in the class
Note that you need to consider whether you want methods from base classes which are inherited (but not overridden) included in the result. The dir() and inspect.getmembers() operations do include base class methods, but use of the __dict__ attribute does not.
If your method is a "regular" method and not a staticmethod, classmethod etc.
There is a little hack I came up with -
for k, v in your_class.__dict__.items():
if "function" in str(v):
print(k)
This can be extended to other type of methods by changing "function" in the if condition correspondingly.
Tested in Python 2.7 and Python 3.5.
Try
print(help(ClassName))
It prints out methods of the class
I just keep this there, because top rated answers are not clear.
This is simple test with not usual class based on Enum.
# -*- coding: utf-8 -*-
import sys, inspect
from enum import Enum
class my_enum(Enum):
"""Enum base class my_enum"""
M_ONE = -1
ZERO = 0
ONE = 1
TWO = 2
THREE = 3
def is_natural(self):
return (self.value > 0)
def is_negative(self):
return (self.value < 0)
def is_clean_name(name):
return not name.startswith('_') and not name.endswith('_')
def clean_names(lst):
return [ n for n in lst if is_clean_name(n) ]
def get_items(cls,lst):
try:
res = [ getattr(cls,n) for n in lst ]
except Exception as e:
res = (Exception, type(e), e)
pass
return res
print( sys.version )
dir_res = clean_names( dir(my_enum) )
inspect_res = clean_names( [ x[0] for x in inspect.getmembers(my_enum) ] )
dict_res = clean_names( my_enum.__dict__.keys() )
print( '## names ##' )
print( dir_res )
print( inspect_res )
print( dict_res )
print( '## items ##' )
print( get_items(my_enum,dir_res) )
print( get_items(my_enum,inspect_res) )
print( get_items(my_enum,dict_res) )
And this is output results.
3.7.7 (default, Mar 10 2020, 13:18:53)
[GCC 9.2.1 20200306]
## names ##
['M_ONE', 'ONE', 'THREE', 'TWO', 'ZERO']
['M_ONE', 'ONE', 'THREE', 'TWO', 'ZERO', 'name', 'value']
['is_natural', 'is_negative', 'M_ONE', 'ZERO', 'ONE', 'TWO', 'THREE']
## items ##
[<my_enum.M_ONE: -1>, <my_enum.ONE: 1>, <my_enum.THREE: 3>, <my_enum.TWO: 2>, <my_enum.ZERO: 0>]
(<class 'Exception'>, <class 'AttributeError'>, AttributeError('name'))
[<function my_enum.is_natural at 0xb78a1fa4>, <function my_enum.is_negative at 0xb78ae854>, <my_enum.M_ONE: -1>, <my_enum.ZERO: 0>, <my_enum.ONE: 1>, <my_enum.TWO: 2>, <my_enum.THREE: 3>]
So what we have:
dir provide not complete data
inspect.getmembers provide not complete data and provide internal keys that are not accessible with getattr()
__dict__.keys() provide complete and reliable result
Why are votes so erroneous? And where i'm wrong? And where wrong other people which answers have so low votes?
There's this approach:
[getattr(obj, m) for m in dir(obj) if not m.startswith('__')]
When dealing with a class instance, perhaps it'd be better to return a list with the method references instead of just names¹. If that's your goal, as well as
Using no import
Excluding private methods (e.g. __init__) from the list
It may be of use. You might also want to assure it's callable(getattr(obj, m)), since dir returns all attributes within obj, not just methods.
In a nutshell, for a class like
class Ghost:
def boo(self, who):
return f'Who you gonna call? {who}'
We could check instance retrieval with
>>> g = Ghost()
>>> methods = [getattr(g, m) for m in dir(g) if not m.startswith('__')]
>>> print(methods)
[<bound method Ghost.boo of <__main__.Ghost object at ...>>]
So you can call it right away:
>>> for method in methods:
... print(method('GHOSTBUSTERS'))
...
Who you gonna call? GHOSTBUSTERS
¹ An use case:
I used this for unit testing. Had a class where all methods performed variations of the same process - which led to lengthy tests, each only a tweak away from the others. DRY was a far away dream.
Thought I should have a single test for all methods, so I made the above iteration.
Although I realized I should instead refactor the code itself to be DRY-compliant anyway... this may still serve a random nitpicky soul in the future.
This also works:
In mymodule.py:
def foo(x):
return 'foo'
def bar():
return 'bar'
In another file:
import inspect
import mymodule
method_list = [ func[0] for func in inspect.getmembers(mymodule, predicate=inspect.isroutine) if callable(getattr(mymodule, func[0])) ]
Output:
['foo', 'bar']
From the Python docs:
inspect.isroutine(object)
Return true if the object is a user-defined or built-in function or method.
def find_defining_class(obj, meth_name):
for ty in type(obj).mro():
if meth_name in ty.__dict__:
return ty
So
print find_defining_class(car, 'speedometer')
Think Python page 210
You can use a function which I have created.
def method_finder(classname):
non_magic_class = []
class_methods = dir(classname)
for m in class_methods:
if m.startswith('__'):
continue
else:
non_magic_class.append(m)
return non_magic_class
method_finder(list)
Output:
['append',
'clear',
'copy',
'count',
'extend',
'index',
'insert',
'pop',
'remove',
'reverse',
'sort']
methods = [(func, getattr(o, func)) for func in dir(o) if callable(getattr(o, func))]
gives an identical list as
methods = inspect.getmembers(o, predicate=inspect.ismethod)
does.
I know this is an old post, but just wrote this function and will leave it here is case someone stumbles looking for an answer:
def classMethods(the_class,class_only=False,instance_only=False,exclude_internal=True):
def acceptMethod(tup):
#internal function that analyzes the tuples returned by getmembers tup[1] is the
#actual member object
is_method = inspect.ismethod(tup[1])
if is_method:
bound_to = tup[1].im_self
internal = tup[1].im_func.func_name[:2] == '__' and tup[1].im_func.func_name[-2:] == '__'
if internal and exclude_internal:
include = False
else:
include = (bound_to == the_class and not instance_only) or (bound_to == None and not class_only)
else:
include = False
return include
#uses filter to return results according to internal function and arguments
return filter(acceptMethod,inspect.getmembers(the_class))
use inspect.ismethod and dir and getattr
import inspect
class ClassWithMethods:
def method1(self):
print('method1')
def method2(self):
print('method2')
obj=ClassWithMethods()
method_names = [attr for attr in dir(obj) if inspect.ismethod(getattr(obj,attr))
print(method_names)
output:
[[('method1', <bound method ClassWithMethods.method1 of <__main__.ClassWithMethods object at 0x00000266779AF388>>), ('method2', <bound method ClassWithMethods.method2 of <__main__.ClassWithMethods object at 0x00000266779AF388>>)]]
None of the above worked for me.
I've encountered this problem while writing pytests.
The only work-around I found was to:
1- create another directory and place all my .py files there
2- create a separate directory for my pytests and then importing the classes I'm interested in
This allowed me to get up-to-dated methods within the class - you can change the method names and then use print(dir(class)) to confirm it.
For my use case, I needed to distinguish between class methods, static methods, properties, and instance methods. The inspect module confuses the issue a bit (particularly with class methods and instance methods), so I used vars based on a comment on this SO question. The basic gist is to use vars to get the __dict__ attribute of the class, then filter based on various isinstance checks. For instance methods, I check that it is callable and not a class method. One caveat: this approach of using vars (or __dict__ for that matter) won't work with __slots__. Using Python 3.6.9 (because it's what the Docker image I'm using as my interpreter has):
class MethodAnalyzer:
class_under_test = None
#classmethod
def get_static_methods(cls):
if cls.class_under_test:
return {
k for k, v in vars(cls.class_under_test).items()
if isinstance(v, staticmethod)
}
return {}
#classmethod
def get_class_methods(cls):
if cls.class_under_test:
return {
k for k, v in vars(cls.class_under_test).items()
if isinstance(v, classmethod)
}
return {}
#classmethod
def get_instance_methods(cls):
if cls.class_under_test:
return {
k for k, v in vars(cls.class_under_test).items()
if callable(v) and not isinstance(v, classmethod)
}
return {}
#classmethod
def get_properties(cls):
if cls.class_under_test:
return {
k for k, v in vars(cls.class_under_test).items()
if isinstance(v, property)
}
return {}
To see it in action, I created this little test class:
class Foo:
#staticmethod
def bar(baz):
print(baz)
#property
def bleep(self):
return 'bloop'
#classmethod
def bork(cls):
return cls.__name__
def flank(self):
return 'on your six'
then did:
MethodAnalyzer.class_under_test = Foo
print(MethodAnalyzer.get_instance_methods())
print(MethodAnalyzer.get_class_methods())
print(MethodAnalyzer.get_static_methods())
print(MethodAnalyzer.get_properties())
which output
{'flank'}
{'bork'}
{'bar'}
{'bleep'}
In this example I'm discarding the actual methods, but if you needed to keep them you could just use a dict comprehension instead of a set comprehension:
{
k, v for k, v in vars(cls.class_under_test).items()
if callable(v) and not isinstance(v, classmethod)
}
This is just an observation. "encode" seems to be a method for string objects
str_1 = 'a'
str_1.encode('utf-8')
>>> b'a'
However, if str1 is inspected for methods, an empty list is returned
inspect.getmember(str_1, predicate=inspect.ismethod)
>>> []
So, maybe I am wrong, but the issue seems to be not simple.
To produce a list of methods put the name of the method in a list without the usual parenthesis. Remove the name and attach the parenthesis and that calls the method.
def methodA():
print("# MethodA")
def methodB():
print("# methodB")
a = []
a.append(methodA)
a.append(methodB)
for item in a:
item()
Just like this
pprint.pprint([x for x in dir(list) if not x.startswith("_")])
class CPerson:
def __init__(self, age):
self._age = age
def run(self):
pass
#property
def age(self): return self._age
#staticmethod
def my_static_method(): print("Life is short, you need Python")
#classmethod
def say(cls, msg): return msg
test_class = CPerson
# print(dir(test_class)) # list all the fields and methods of your object
print([(name, t) for name, t in test_class.__dict__.items() if type(t).__name__ == 'function' and not name.startswith('__')])
print([(name, t) for name, t in test_class.__dict__.items() if type(t).__name__ != 'function' and not name.startswith('__')])
output
[('run', <function CPerson.run at 0x0000000002AD3268>)]
[('age', <property object at 0x0000000002368688>), ('my_static_method', <staticmethod object at 0x0000000002ACBD68>), ('say', <classmethod object at 0x0000000002ACF0B8>)]
If you want to list only methods of a python class
import numpy as np
print(np.random.__all__)

Pythonic way to "flatten" object hierarchy to nested dicts?

I need to "flatten" objects into nested dicts of the object's properties. The objects I want to do this with are generally just containers for basic types or other objects which act in a similar way. For example:
class foo(object):
bar = None
baz = None
class spam(object):
eggs = []
x = spam()
y = foo()
y.bar = True
y.baz = u"boz"
x.eggs.append(y)
What I need to "flatten" this to is:
{ 'eggs': [ { 'bar': True, 'baz': u'boz' } ] }
Is there anything in the stdlib which can do this for me? If not, would I have to test isinstance against all known base-types to ensure I don't try to convert an object which can't be converted (eg: bool)?
Edit:
These are objects are being returned to my code from an external library and therefore I have no control over them. I could use them as-is in my methods, but it would be easier (safer?) to convert them to dicts - especially for unit testing.
Code: You may need to handle other iterable types though:
def flatten(obj):
if obj is None:
return None
elif hasattr(obj, '__dict__') and obj.__dict__:
return dict([(k, flatten(v)) for (k, v) in obj.__dict__.items()])
elif isinstance(obj, (dict,)):
return dict([(k, flatten(v)) for (k, v) in obj.items()])
elif isinstance(obj, (list,)):
return [flatten(x) for x in obj]
elif isinstance(obj, (tuple,)):
return tuple([flatten(x) for x in obj])
else:
return obj
Bug?
In your code instead of:
class spam(object):
eggs = []
x = spam()
x.eggs.add(...)
please do:
class spam(object):
eggs = None #// if you need this line at all though
x = spam()
x.eggs = []
x.eggs.add(...)
If you do not, then all instances of spam will share the same eggs list.
No, there is nothing in the standardlib. Yes, you would have to somehow test that the types are basic types like str, unicode, bool, int, float, long...
You could probably make a registry of methods to "serialize" different types, but that would only be useful if you have some types that should not have all it's attributes serialized, for example, or if you also need to flatten class attributes, etc.
Almost every object has a dictionary (called __dict__), with all its methods and members.
With some type checking, you can then write a function that filters out only the members you are interested in.
It is not a big task, but as chrispy said, it could worth to try looking at your problem from a completely different perspective.
Well, I'm not very proud of this, but is possible to do the following:
Create a super class that has the serialization method and loop through its properties.
At runtime extend your classes using bases at runtime
Execute the class from the new super class. It should be able to access the dict data from the children and work.
Here is an example:
class foo(object):
def __init__(self):
self.bar = None
self.baz = None
class spam(object):
delf __init__(self):
self.eggs = []
class Serializable():
def serialize(self):
result = {}
for property in self.__dict__.keys():
result[property] = self.__dict__[property]
return result
foo.__bases__ += (Serializable,)
spam.__bases__ += (Serializable,)
x = spam()
y = foo()
y.bar = True
y.baz = u"boz"
x.eggs.append(y)
y.serialize()
Things to point out. If you do not set the var is init the dict willnot work 'cause it is accessing the instance variables not the class variables (I suppose you meant instance ones). Second, make sure Serializable DOES NOT inherit from object, it is does you will have a
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution
Hope it helps!
Edit: If you are just copying the dict use the deepcopy module, this is just an example :P

Using Variables for Class Names in Python?

I want to know how to use variables for objects and function names in Python. In PHP, you can do this:
$className = "MyClass";
$newObject = new $className();
How do you do this sort of thing in Python? Or, am I totally not appreciating some fundamental difference with Python, and if so, what is it?
Assuming that some_module has a class named "class_name":
import some_module
klass = getattr(some_module, "class_name")
some_object = klass()
I should note that you should be careful here: turning strings into code can be dangerous if the string came from the user, so you should keep security in mind in this situation. :)
One other method (assuming that we still are using "class_name"):
class_lookup = { 'class_name' : class_name }
some_object = class_lookup['class_name']() #call the object once we've pulled it out of the dict
The latter method is probably the most secure way of doing this, so it's probably what you should use if at all possible.
In Python,
className = MyClass
newObject = className()
The first line makes the variable className refer to the same thing as MyClass. Then the next line calls the MyClass constructor through the className variable.
As a concrete example:
>>> className = list
>>> newObject = className()
>>> newObject
[]
(In Python, list is the constructor for the list class.)
The difference is that in PHP, you represent the name of the class you want to refer to as a string, while in Python you can reference the same class directly. If you must use a string (for example if the name of the class is created dynamically), then you will need to use other techniques.
If you need to create a dynamic class in Python (i.e. one whose name is a variable) you can use type() which takes 3 params:
name, bases, attrs
>>> class_name = 'MyClass'
>>> klass = type(class_name, (object,), {'msg': 'foobarbaz'})
<class '__main__.MyClass'>
>>> inst = klass()
>>> inst.msg
foobarbaz
Note however, that this does not 'instantiate' the object (i.e. does not call constructors etc. It creates a new(!) class with the same name.
If you have this:
class MyClass:
def __init__(self):
print "MyClass"
Then you usually do this:
>>> x = MyClass()
MyClass
But you could also do this, which is what I think you're asking:
>>> a = "MyClass"
>>> y = eval(a)()
MyClass
But, be very careful about where you get the string that you use "eval()" on -- if it's come from the user, you're essentially creating an enormous security hole.
Update: Using type() as shown in coleifer's answer is far superior to this solution.
I use:
newObject = globals()[className]()
I prefer using dictionary to store the class to string mapping.
>>> class AB:
... def __init__(self, tt):
... print(tt, "from class AB")
...
>>> class BC:
... def __init__(self, tt):
... print(tt, "from class BC")
...
>>> x = { "ab": AB, "bc": BC}
>>> x
{'ab': <class '__main__.AB'>, 'bc': <class '__main__.BC'>}
>>>
>>> x['ab']('hello')
hello from class AB
<__main__.AB object at 0x10dd14b20>
>>> x['bc']('hello')
hello from class BC
<__main__.BC object at 0x10eb33dc0>

Categories