I'm trying to call a method within a class MyClass and have its value returned.
class MyClass:
def __init__(self):
print " Class Initialized"
def gather_path(self):
self.tld_object = Tld.objects.get(id=3,FKToClient=User.pk)
return self.tld_object
How do I return the value of self.tld_object by importing my class in Python intrepreter.
I'm importing like:
from MyApp.MyClass import gather_path()
I know, this is quite basic - I'm relatively new to OOP in Python.
how do I then call this method to return the value of return self.tld_object within gather_path() method?
It depends on what you're trying to do, but typically, I think the code importing your class would look like this:
from MyApp import MyClass
my_instance = MyClass()
value = my_instance.gather_path()
The value variable will now contain tld_object's value.
If you don't want to instantiate MyClass in order to call get_path(), you need to make get_path() either a class or static method.
From your example, it's not clear that you need to set self.tld_object, since you're just returning it from gather_path() anyway, unless other methods are relying on that state under the hood. If you are, though, it would be better practice to declare it in __init__, even if you set it to None. Alternatively, if all instances of MyClass are going to use the same value of tld_object, you could make it a class variable, and just declare it outside of any method, like so:
class MyClass:
tld_object = Tld.objects.get(id=3,FKToClient=User.pk)
def gather_path(self):
return self.tld_object
Not sure how much of that is relevant to your needs, it's a bit hard to tell from the given example. If I were writing this (given what you've said so far), I'd do the following:
class MyClass:
def __init__(self):
self.tld_object = Tld.objects.get(id=3,FKToClient=User.pk)
# Maybe raise an exception or something if self.tld_object doesn't get set right
# Example of how to access tld_object from another method
def print_tld_object(self):
print self.tld_object
If you need to reach tld_object from outside the class, you would do the following in the other module:
from MyApp import MyClass
my_instance = MyClass()
tld = my_instance.tld_object
Related
I import a class Foo that has a default parameter dir upon which if performs a function doit. How can I change the default dir? Do I need to inherit this class and then change it, how?
class Foo(object):
def __init__(self, dir='xxx'):
self.bar = doit(dir) # fails because xxx is wrong
why don't you just provide a different argument when you construct an instance of the class:
foo = Foo(dir='something else')
btw: dir is a python built-in and therefore not the best choice as variable name.
if you want the default changed, you can inherit indeed:
class MyFoo(Foo):
def __init__(self, d='somethig else'):
super().__init__(d=d)
Just create a factory function for Foo objects and be done with it:
def create_foo():
return Foo(dir='my correct value goes here')
Since you're importing Foo, you could go a step further and just shadow Foo like this:
def Foo():
import foo
return foo.Foo(dir='my correct value goes here')
Of course you can inherit from Foo. Be sure to look up how to call the base
class constructors. I find that sooo hard to memorize that I just end up google it. Every. Single. Time.
BTW: Looks like #hiro protagonist already has the calling super figured out.
Maybe the title is a bit misleading, however I wanted to create a simple decorator to decorate some class methods as "allowed" in an RPC mechanism, but I'm stuck on a strange error when trying to access class variables (Python 2.7.5). Check the code below:
class myclass():
rpcallowedmethods = []
def __init__(self):
pass
def rpcenabled(fn):
print fn
print globals()
print myclass
#rpcenabled
def somefunc(self,param):
pass
c = myclass()
Exception: NameError: global name 'myclass' is not defined
Anyone can explain the reason behind this to me?
EDIT:
What I'm asking is more about the fact that python executes the decorator defined in a class and run against decorated classmethods even prior having the class in the globals, so I believed it's more of a logical "bug" in the python implementation than a seemingly obvious NameError
The actual class object is only assigned to its name after its definition is finished. Thus you cannot use the class name during its definition. You can either create a decorator outside of the class to which you explicitly pass the list you want to fill, or use the following:
class myclass():
rpcmethods = []
def _rpcallowed(fct, l=rpcmethods):
l.append(fct)
return fct
#_rpcallowed
def myfct(): pass
Note that the default parameter (l=rpcmethods) is a workaround as you cannot access a class variable inside of a function without a reference to the class or an instance.
The variant with the decorator outside of the class would probably qualify as being "cleaner" than this as it's explicit and reusable, but it would be a bit more code and less specific.
You're abusing decorators. A decorator is meant to add something to thing object is given. "decorating" it somehow.
The more usual way to do something like this would be to decorate both the method and the class. Metaclasses are another way to solve this problem. They're more powerful, but are overkill for your current problem. However, directly decorating the functions might be all you need to do. And save collating the rpc functions for when a proxy is made.
from types import FunctionType
def enable_rpc(func):
func.rpc_enabled = True
return func
def rpc_enabled_class(cls):
functions = [attr for attr in vars(cls).values()
if isinstance(attr, FunctionType)]
cls._rpc_enabled_methods = [
func for func in functions
if getattr(func, "rpc_enabled", False)
]
return cls
#rpc_enabled_class
class SampleClass(object):
#enable_rpc
def my_func(self):
pass
print(SampleClass._rpc_enabled_methods)
Strange error?
print myclass
caused the error. You can't use the name myclass in its definition...
For different data types, like string, there are methods that you call by adding a dot after, such as:
"string {0}".format(stringy)
or
listx.remove(x)
How is the information being passed to the method? How can I write a function like that?
class YourObject(object):
def do_something(self):
print('doing something')
Then you can use your object:
your_object = YourObject()
your_object.do_something()
This shows how to create an object, and call a method on it (like theexamples you provided in your post).
There are way more in-depth tutorials/blogs about object creation and custom classes. A good place to start is always the standard documentation.
You can create a custom class and then include whatever methods you want. Below is an example:
>>> class MyClass(object): # Define class MyClass
... def __init__(self): # Define MyClass' constructor method
... self.name = "Me" # Make an attribute
... def getName(self): # Define method getName
... return self.name # Return MyClass' attribute name (self.name)
...
>>> test = MyClass() # Initialize (create an instance of) MyClass
>>> print test.getName() # Print the name attribute by calling the getName method
Me
>>>
Basically, you are working with OOP (Object-Oriented Programming). However, since this concept is so large, I can't demonstrate/explain everything you can do with it here (otherwise my post would be enormous). My advice is to research OOP and Python classes. There are many good tutorials you can find. I gave one above; here is another:
I'm not really sure how best to explain what I want, so I'll just show some code:
class Stuffclass():
def add(self, x, y):
return x + y
def subtract(self, x, y):
return x - y
# imagine that there are 20-30 other methods in here (lol)
class MyClass:
def __init__(self):
self.st = Stuffclass()
def doSomething(self):
return self.st.add(1, 2)
m = MyClass()
m.doSomething() # will print 3
# Now, what I want to be able to do is:
print m.add(2, 3) # directly access the "add" method of MyClass.st
print m.subtract(10, 5) # directly access the "subtract" method of MyClass.st
m.SomeMethod() # execute function MyClass.st.SomeMethod
I know I could do something like this:
class MyClass:
def __init__(self):
self.st = Stuffclass()
self.add = self.st.add
self.subtract = self.st.subtract
...but this requires manually assigning all possible attributes.
I'm writing all the classes so I can guarantee no name collisions.
Making MyClass a subclass of Stuffclass won't work, because I actually am using this in a plugin-based application, where MyClass loads other code dynamically using import. This means MyClass can't subclass from the plugin, because the plugin could be anything that follows my API.
Advice please?
I believe that writing a getattr function for your class will let you do what you want.
Called when an attribute lookup has not found the attribute in the usual places (i.e. it is not an instance attribute nor is it found in the class tree for self). name is the attribute name. This method should return the (computed) attribute value or raise an AttributeError exception
So something as simple as:
def __getattr__(self, name):
if hasattr(self.st, name):
return getattr(self.st, name)
else:
raise AttributeError
should do roughly what you're after.
But, having answered (I think) the question you asked, I'm going to move on to the question I think you should have asked.
I actually am using this in a plugin-based application, where MyClass loads other code dynamically using import. This means MyClass can't subclass from the plugin, because the plugin could be anything that follows my API
I can see why MyClass can't be a subclass of StuffClass; but couldn't StuffClass be a subclass of MyClass? If you defined the inheritance that way, you'd have a guarantee what StuffClass implements all the basic stuff in MyClass, and also that your instances of StuffClass have all the extra methods defined in StuffClass.
From your mention that the plugins need to "follows my API", I'm assuming that might be a case where you need to ensure that the plugins implement a set of methods in order to conform with the API; but since the implementation of the methods is going to depend on the specifics of the plugin, you can't provide those functions in MyClass. In that case, it sounds as though defining an Abstract Base Class that your plugins are required to inherit from might be useful for you.
Use __getattr__ to delegate the calls to Stuffclass's instance:
class MyClass:
def __init__(self):
self.st = Stuffclass()
def __getattr__(self,attr):
return getattr(self.st,attr)
Demo:
>>> from so import *
>>> m = MyClass()
>>> m.add(1,2)
3
>>> m.subtract(100,2)
98
I'm trying to wrap a function when defining the class, use method in this class's instance
Below is a code that works
class A(object):
def __init__(self):
pass
#self_decorator
def to_be_decorated(self):
pass
def self_decorator(fn):
from functools import wraps
#wraps(fn)
def wrapper(*args, **kwargs):
self = args[0]
return self.app.route('/twip')(fn(*args, **kwargs))
return wrapper
What I actually tries to get:
class A(object):
def __init__(self):
self.app = APP()
#self.app.wrapper_function # which apparently doesn't work
def to_be_decorated(self):
pass
So, is it possible for my way of decorating to work?
At the class definition there's no self as the class do not exists yet and cannot be instantiated.
You can use
class A(object):
app = APP()
#app.wrapper_function
def to_be_decorated(self):
pass
But that would be a class variable.
A decorator is just a function that gets called at the time of definition.
When you write this:
#self.app.wrapper_function # which apparently doesn't work
def to_be_decorated(self):
pass
it's roughly the same as writing this:
def to_be_decorated(self):
pass
to_be_decorated = self.app.wrapper_function(to_be_decorated)
Once you see it that way, it's obvious why this doesn't work, and couldn't possibly work.
First, A's class definition doesn't have a self variable, nor does A have a member app that could be accessed even if it did. Instead, each instance of A will have its own unique self.app.
And even if you wish the interpreter could just "do what I mean", if you think about it, that can't mean anything. You want to call "the" self.app.wrapper_function method, but there is no such thing. Unless you read through all of the relevant code everywhere the method could be defined or redefined, there's absolutely no guarantee that the self.app.wrapper_function from different instances of A will even have the same underlying func_code. But, even if they did, self.app.wrapper_function is a bound method—a method bound together with the object it's called on—so they're still all different from each other.
There are plenty of ways around this, but they're all going to be the same trick: Use some kind of indirection to get a function which isn't a member of self.app or self, and references self.app at call time. This is basically what your self_decorator does, and it's unavoidable.