Storing Method In Dictionary in Python - python

I am trying to write a program that can initialize classes from various submodules. In order to make it easy to expand the modules in future, I would like to store their constructor functions and some of the key functions in dictionaries. I am getting the issue with the functions not being recognized as an attribute and am not certain how to fix this. It seems to be fine for the constructors. The code should look something like this:
import my_class
class_ctor = {"my_class":my_class.my_class, ...}
class_func = {"my_class":my_class.my_class.func, ...}
my_inst = class_ctor["my_class"](what,ever,arguments)
my_inst.class_func["my_class"](some,other,arguments)
Inside my_class.py:
class my_class:
def __init__(self):
...
def func(...):
...
Is there a way that I could achieve something like this? I have seen a few examples which have dispatchers that work in a similar way, but would like to abstract this to methods.
I appreciate any help!

The problem is this line:
my_inst.class_func["my_class"](some,other,arguments)
class_func doesn't belong to my_inst (from what you've shown).

Related

Python classes/subclasses

I've read over the Python documents regarding classes and subclasses but I've still not seen anything to accomplish what I'm after. Maybe I'm just using the wrong terminology for it. But basically I have created a class and now I want to create a subclass that will have properties so that I can call them similarly to the following:
import MyClass
mc = MyClass()
print mc.MySubclass.Property
The reason for this is because currently I have several properties in my class and I'd like to make it easier to get them. Like currently I'm just saying mc.category_value where "category" represents a might be like "color" and "value" would be like "red", so it looks like "mc.color_red" or "mc.color_blue" but I'd rather be able to say "mc.color.red". Is this possible?
So inner classes, are possible:
class Foo():
x = 1
def y():
print("hello")
class Bar():
z = 2
x = Foo.Bar()
print(x.z)
print(Foo.Bar.z) # added this example to be closer to what you want
I use these often with the inner class being private, called something like _Bar when I want a struct like object that I don't want to expose. But we also use them when they are like you say, property objects of a factory or something.

Passing an instance to __init__. Is this a good idea?

Suppose I have a simple class like this:
class Class1(object):
def __init__(self, property):
self.property = property
def method1(self):
pass
An instances of Class1 returns a value that can be used in other class:
class Class2(object):
def __init__(self, instance_of_class1, other_property):
self.other_property = other_property
self.instance_of_class1 = instance_of_class1
def method1(self):
# A method that uses self.instance_of_class1.property and self.other_property
This is working. However, I have the feeling that this is not a very common approach and maybe there are alternatives. Having said this, I tried to refactor my classes to pass simpler objects to Class2, but I found that passing the whole instance as an argument actually simplifies the code significantly. In order to use this, I have to do this:
instance_of_class1 = Class1(property=value)
instance_of_class2 = Class2(instance_of_class1, other_property=other_value)
instance_of_class2.method1()
This is very similar to the way some R packages look like. Is there a more "Pythonic" alternative?
There's nothing wrong with doing that, though in this particular example it looks like you could just as easily do
instance_of_class2 = Class2(instance_of_class1.property, other_property=other_value).
But if you find you need to use other properties/methods of Class1 inside of Class2, just go ahead and pass the whole Class1 instance into Class2. This kind of approach is used all the time in Python and OOP in general. Many common design patterns call for a class to take an instance (or several instances) of other classes: Proxy, Facade, Adapter, etc.

Set Python attributes from a list, but recall them outside of a list

Not sure if this the recommended way of doing things in Python. I have a class with a bunch of attributes, like so
class MyClass:
def __init__(self):
self.attr1 = "first_value"
self.attr2 = "second_value"
...
However, this is tedious, I want to be able to do this in a loop:
self.attr_list = ["attr1", "attr2", "another_attr",...]
def __init__(self, values_list):
self.attr_values = [some_func(i) for i in values_list]
But I also later want to call these values like so:
foo = MyClass(values_list)
...
bar = foo.attr1
myFunc(foo.another_attr, ..., some_other_parameters)
So the question is, how do I avoid the tedious first method where the line for each attribute is hard-coded, but still get the convenience of referring to an attribute without having to know/remember where in the list it is?
Hope this is clearer.
Thanks
P.S. I'm using Python 3
I'm not sure I understand the question. Are you looking for setattr? Something like this:
def assign(self, attr_names, value_list):
for i in range(len(attr_names)):
setattr(self, attr_names[i], some_func(value_list[i]))
You can use it like that:
foo.assign(["attr1", "attr2"], value_list)
print(foo.attr1)
I don't think that using setattr is wrong per se however I advice using dictionaries instead since you might overwrite other attributes by accident, for example consider this:
foo.assign(["assign"], [1])
foo.assign(["assign"], [1]) # <-- exception now

How to access globals from a different point in code

I'm trying to find a way of basically doing a late eval, using context from a different location in the code. As an example, I have a class Friend, and it can be used like this:
>>> class A:
... friend = Friend('B')
...
>>> class B:
... friend = Friend('A')
...
>>> A.friend.getobject()
<class '__main__.B'>
However, Friend is defined elsewhere in the code, in a separate library, and would look something like this:
class Friend:
def __init__(self, objname):
self.objname = objname
def getobject(self):
return eval(self.objname, original_context)
The sqlalchemy ORM has a similar pattern for defining columns, but they implement it by tracking all owning classes (i.e. tables) in a session. I could do something similar if I need to, but I'd like to know if there is another way to do this. I've been looking at frames and the interpreter stack, and I think I can get to the relevant frame's locals using something like inspect.stack()[1][0].f_locals, but I would have to do this in Frame.__init__ which is called before the object is defined.
My questions is how to find original_context, but only at the time it is needed. This comes down to two issues:
1. How to access the environment (or frame?) in which Friend was instantiated.
2. How to access it at the time getobject is called.
You will have to use the fully qualified classname, ie:
class A:
friend = Friend('themodule.B')
And then take that string, extract out the module and import the B class, and generate it like this.
However, in general, a better way is to do:
class A:
friend = Friend(B)
In this case B isn't defined at that point, but you can easily do:
class A:
pass
class B:
pass
A.friend = Friend(B)
B.friend = Friend(A)

Python global/package alias implementation class

I have that strange feeling this is an easy question.
I want to be able to "alias" a class type so i can swap out the implementation at a package level. I dont want to have X amount of import X as bah scattered throughout my code...
Aka. How can I do something like the below:
class BaseClass(object):
def __init__(self): pass
def mymthod(self): pass
def mymthod1(self): pass
def mymthod2(self): pass
class Implementation(BaseClass):
def __init__(self):
BaseClass.__init__()
Seperate package...
#I dont want thse scattered through out modules,
#i want them in one place where i can change one and change implementations
#I tried putting it in the package init but no luck
import Implementation as BaseClassProxy
class Client(BaseClassImpl):
def __init__(self):
BaseClassImpl.__init__(self)
In any file (where this fits best is up to you, probably wherever Implementation was defined):
BaseClassProxy = Implementation
Since classes are first class objects in Python, you can pretty much bind them to any variable and use them the same way. In this case, you can make an alias for the class.
just put something like
BaseClassProxy = Implementation
in the module, then do:
from module import BaseClassProxy

Categories