I frequently have simple classes which I'll only ever want a single instance of. As a simple example:
import datetime
import sys
class PS1(object):
def __repr__(self):
now = datetime.datetime.now()
return str(now.strftime("%H:%M:%S"))
sys.ps1 = PS1()
Is there a way that I could somehow combine the definition and instantiation into a single step and achieve the same results?
As another example, just as something that is simple enough to understand.
class Example(object):
def methodOne(self, a, b):
return a + b
def methodTwo(self, a, b):
return a * b
example = Example()
I googled around and found nothing (lots of people throwing around the words one-off and anonymous but nobody seems to be talking about the same thing I am). I tried this, but it didn't work:
example = class(object):
def methodOne(self, a, b):
return a + b
def methodTwo(self, a, b):
return a * b
I realize I don't gain much, just one line I don't have to type plus one fewer things in my namespace, so I understand if this doesn't exist.
I think you don't see this often because it's really hard to read, but ...
sys.ps1 = type('PS1', (object,), {'__repr__': lambda self: datetime.datetime.now().strftime('%H:%M:%S')})()
would do the trick here...
I use type to dynmically create a class (the arguments are name, base classes, class dictionary). The class dictionary just consists of a single function __repr__ in this case.
Hopefully we can agree that the full format is much easier to grok and use ;-).
You could use a simple class decorator to replace the class with an instance of it:
def instantiator(cls):
return cls()
Then use it like this:
#instantiator
class PS1(object):
def __repr__(self):
now = datetime.datetime.now()
return str(now.strftime("%H:%M:%S"))
Then:
>>> PS1
11:53:37
If you do this, you might want to make the class name lowercase, since it will ultimately be used to name an instance, not a class.
This still requires an extra line, but not an extra name in the namespace.
If you really wanted to, you could write a metaclass that does the same thing, but automatically. However, I don't really think this would save much effort over just instantiating the class manually, and it would definitely make the code more complex and difficult to understand.
You could use a metaclass, so you can still use prettier syntax in comparison to #mgilson's answer.
class OneOff(type):
def __new__(cls, name, bases, attrs):
klass = type.__new__(cls, name, bases, attrs)
return klass()
class PS1(object):
__metaclass__ = OneOff
...
However, I'm with the others saying that I'm not sure this is a great idea. I did something like this once, but it was for a very specific usecase, and I'd really think about exploring other avenues first. Also, this looks an awful lot like a singleton/borg, so maybe that would be the better way for you to go.
(#mgilson's answer achieves what you're looking for in the most direct way. I second him on the opinion your original code is better than any of the answers here)
A simpler, more readable alternative, only if you don't need to use any special functions (e.g. __repr__), just use a dict of functions (playing the role of the methods):
fake_obj = dict(method_one = lambda a,b: a+b, method_two = lambda a,b: a*b)
There are two ways to do this in python. One is to instantiate a singleton object which can be done with a decorator, another is to make the class itself the used object with class methods and class variables.
The first option (singleton) looks like this:
def apply_class(*args, **kwargs):
def myclass(c):
c(*args,**kwargs)
return myclass
#apply_class(5)
class mysingleton(object):
def __init__(self, x):
print x
The second option (class methods/variables) looks like this:
class mysingleton:
myvariable = 5
#classmethod
def mymethod(cls):
print cls.myvariable
Related
I am new to opp programming.I wanted to know what to do with a function that is inside the class but does not use self value
For example
class example:
def __init__(self,n):
self.number=n
def get_t(self,t):
return t*t
def main(self):
b=1
k=self.get_t(b)
From the example the function get_t has nothing to do with self value.
So I wanted to know where to place the function get_t or may be how to restructure the class.
Thank you for your consideration
What you're looking for are static methods. To declare a method static do it like this
#staticmethod
def foo():
pass
Nothing. Just let it be, Python won't complain about it and there's nothing fundamentally wrong about methods that doesn't use its instance. If your linter complains about it, you can shut up that warning. These kind of helper functions are often intended to be private methods that aren't intended to be used externally, you may want to prefix the name with underscore to indicate that.
Convert it into a free function. Python is an OOP language, but it's also a mixed paradigm language, unlike Java, for example, you can actually create a function outside of a class declaration. Pythonic code does not necessarily means putting everything into classes, and often a free function is perfectly suitable place for functions that doesn't involve a particular object instance.
def get_t(t):
return t*t
class example:
def main(self):
b=1
k=self.get_t(b)
If you want to be able to call it from the class by doing Example.get_t(blah) without having to have an instance, then you can either use the staticmethod or classmethod decorator. I suggest using classmethod which can do everything that staticmethod can do while the reverse isn't true and it's easier to make classmethod work correctly when you need to override it in a multi inheritance situation. staticmethod has a very tiny performance advantage, but you're microoptimizing if that's your concern.
class example:
#classmethod
def get_t(cls, t):
return t*t
def main(self):
b=1
k=self.get_t(b)
If get_t() is only being called from one method, you can put it as an inner function of that method:
class example:
def main(self):
def get_t(t):
return t * t
b=1
k=self.get_t(b)
With regards to naming, get_xxx is usually a code smell in python. The get_ prefix indicates that the method is likely a getter, and pythonic code usually don't use getters/setters, because the language supports property. What you have on here though, isn't actually a getter but rather a computation method, so it shouldn't be prefixed with get_. A better name might be calculate_t(t) or square(t).
Case 1: If self is there:-
class example:
def get_t(self,t):
return t*t
Then You can not access get_t function directly from class example like example.get_t(t=2) ,it will give you error. But you can access now by creating an object of class like q = example() and then q.get_t(t=2) , it will give you your desired result.
Case 2 : If self is not there:-
class example:
def get_t(t):
return t*t
Now You can directly access get_t function by class example like example.get_t(t=2) ,it will give you your desired result. But now you cannot use get_t function by creating object like q = example() then q.get_t(t=2) it will give you error.
Conclusion :- It all depends on your use case. But when you struck in this type of ambiguity use #staticmethod like given below:-
class example:
#staticmethod
def get_t(t):
return t*t
I hope it may help you.
I have following structure for class.
class foo(object):
def __call__(self,param1):
pass
class bar(object):
def __call__(self,param1,param2):
pass
I have many classes of this type. And i am using this callable class as follows.
classes = [foo(), bar()]
for C in classes:
res = C(param1)
'''here i want to put condition if class takes 1 argumnet just pass 1
parameter otherwise pass two.'''
I have think of one pattern like this.
class abc():
def __init__(self):
self.param1 = 'xyz'
self.param2 = 'pqr'
def something(self, classes): # classes = [foo(), bar()]
for C in classes:
if C.__class__.__name__ in ['bar']:
res = C(self.param1, self.param2)
else:
res = C(self.param2)
but in above solution have to maintain list of class which takes two arguments and as i will add more class to file this will become messy.
I dont know whether this is correct(pythonic) way to do it.
On more idea i have in mind is to check how many argument that class is taking. If its 2 then pass an additional argument otherwise pass 1 argument.I have looked at this solution How can I find the number of arguments of a Python function? . But i am not confident enought that this is the best suited solution to my problem.
Few things about this:
There are only two type of classes in my usecase one with 1 argument and one with 2.
Both class takes first argument same so params1 in both case is same argument i am passing. in case of class with two required parameter i am passing additional argument(params2) containing some data.
Ps : Any help or new idea for this problem are appretiated.
UPD : Updated the code.
Basically, you want to use polymorphism on your object's __call__() method, but you have an issue with your callables signature not being the same.
The plain simple answer to this is: you can only use polymorphism on compatible types, which in this case means that your callables MUST have compatible signatures.
Hopefully, there's a quick and easy way to solve this: just modify your methods signatures so they accept varargs and kwargs:
class Foo(object):
def __call__(self,param1, *args, **kw):
pass
class Bar(object):
def __call__(self, param1, param2, *args, **kw):
pass
For the case where you can't change the callable's signature, there's still a workaround: use a lambda as proxy:
def func1(y, z):
pass
def func2(x):
pass
callables = [func1, lambda y, z: func2(y)]
for c in callables:
c(42, 1138)
Note that this last example is actually known as the adapter pattern
Unrelated: this:
if C.__class__.__name__ in ['bar']:
is a inefficient and convoluted way to write:
if C.__class__.__name__ == 'bar':
which is itself an inefficient, convoluted AND brittle way to write:
if type(C) is bar:
which, by itself, is a possible design smell (there are legit use cases for checking the exact type of an object, but most often this is really a design issue).
For a recursive function we can do:
def f(i):
if i<0: return
print i
f(i-1)
f(10)
However is there a way to do the following thing?
class A:
# do something
some_func(A)
# ...
If I understand your question correctly, you should be able to reference class A within class A by putting the type annotation in quotes. This is called forward reference.
class A:
# do something
def some_func(self, a: 'A')
# ...
See ref below
https://github.com/python/mypy/issues/3661
https://www.youtube.com/watch?v=AJsrxBkV3kc
In Python you cannot reference the class in the class body, although in languages like Ruby you can do it.
In Python instead you can use a class decorator but that will be called once the class has initialized. Another way could be to use metaclass but it depends on what you are trying to achieve.
You can't with the specific syntax you're describing due to the time at which they are evaluated. The reason the example function given works is that the call to f(i-1) within the function body is because the name resolution of f is not performed until the function is actually called. At this point f exists within the scope of execution since the function has already been evaluated. In the case of the class example, the reference to the class name is looked up during while the class definition is still being evaluated. As such, it does not yet exist in the local scope.
Alternatively, the desired behavior can be accomplished using a metaclass like such:
class MetaA(type):
def __init__(cls):
some_func(cls)
class A(object):
__metaclass__=MetaA
# do something
# ...
Using this approach you can perform arbitrary operations on the class object at the time that the class is evaluated.
Maybe you could try calling __class__.
Right now I'm writing a code that calls a class method from within the same class.
It is working well so far.
I'm creating the class methods using something like:
#classmethod
def my_class_method(cls):
return None
And calling then by using:
x = __class__.my_class_method()
It seems most of the answers here are outdated. From python3.7:
from __future__ import annotations
Example:
$ cat rec.py
from __future__ import annotations
class MyList:
def __init__(self,e):
self.data = [e]
def add(self, e):
self.data.append(e)
return self
def score(self, other:MyList):
return len([e
for e in self.data
if e in other.data])
print(MyList(8).add(3).add(4).score(MyList(4).add(9).add(3)))
$ python3.7 rec.py
2
Nope. It works in a function because the function contents are executed at call-time. But the class contents are executed at define-time, at which point the class doesn't exist yet.
It's not normally a problem because you can hack further members into the class after defining it, so you can split up a class definition into multiple parts:
class A(object):
spam= 1
some_func(A)
A.eggs= 2
def _A_scramble(self):
self.spam=self.eggs= 0
A.scramble= _A_scramble
It is, however, pretty unusual to want to call a function on the class in the middle of its own definition. It's not clear what you're trying to do, but chances are you'd be better off with decorators (or the relatively new class decorators).
There isn't a way to do that within the class scope, not unless A was defined to be something else first (and then some_func(A) will do something entirely different from what you expect)
Unless you're doing some sort of stack inspection to add bits to the class, it seems odd why you'd want to do that. Why not just:
class A:
# do something
pass
some_func(A)
That is, run some_func on A after it's been made. Alternately, you could use a class decorator (syntax for it was added in 2.6) or metaclass if you wanted to modify class A somehow. Could you clarify your use case?
If you want to do just a little hacky thing do
class A(object):
...
some_func(A)
If you want to do something more sophisticated you can use a metaclass. A metaclass is responsible for manipulating the class object before it gets fully created. A template would be:
class AType(type):
def __new__(meta, name, bases, dct):
cls = super(AType, meta).__new__(meta, name, bases, dct)
some_func(cls)
return cls
class A(object):
__metaclass__ = AType
...
type is the default metaclass. Instances of metaclasses are classes so __new__ returns a modified instance of (in this case) A.
For more on metaclasses, see http://docs.python.org/reference/datamodel.html#customizing-class-creation.
If the goal is to call a function some_func with the class as an argument, one answer is to declare some_func as a class decorator. Note that the class decorator is called after the class is initialized. It will be passed the class that is being decorated as an argument.
def some_func(cls):
# Do something
print(f"The answer is {cls.x}")
return cls # Don't forget to return the class
#some_func
class A:
x = 1
If you want to pass additional arguments to some_func you have to return a function from the decorator:
def some_other_func(prefix, suffix):
def inner(cls):
print(f"{prefix} {cls.__name__} {suffix}")
return cls
return inner
#some_other_func("Hello", " and goodbye!")
class B:
x = 2
Class decorators can be composed, which results in them being called in the reverse order they are declared:
#some_func
#some_other_func("Hello", "and goodbye!")
class C:
x = 42
The result of which is:
# Hello C and goodbye!
# The answer is 42
What do you want to achieve? It's possible to access a class to tweak its definition using a metaclass, but it's not recommended.
Your code sample can be written simply as:
class A(object):
pass
some_func(A)
If you want to refer to the same object, just use 'self':
class A:
def some_func(self):
another_func(self)
If you want to create a new object of the same class, just do it:
class A:
def some_func(self):
foo = A()
If you want to have access to the metaclass class object (most likely not what you want), again, just do it:
class A:
def some_func(self):
another_func(A) # note that it reads A, not A()
Do remember that in Python, type hinting is just for auto-code completion therefore it helps IDE to infer types and warn user before runtime. In runtime, type hints almost never used(except in some cases) so you can do something like this:
from typing import Any, Optional, NewType
LinkListType = NewType("LinkList", object)
class LinkList:
value: Any
_next: LinkListType
def set_next(self, ll: LinkListType):
self._next = ll
if __name__ == '__main__':
r = LinkList()
r.value = 1
r.set_next(ll=LinkList())
print(r.value)
And as you can see IDE successfully infers it's type as LinkList:
Note: Since the next can be None, hinting this in the type would be better, I just didn't want to confuse OP.
class LinkList:
value: Any
next: Optional[LinkListType]
It's ok to reference the name of the class inside its body (like inside method definitions) if it's actually in scope... Which it will be if it's defined at top level. (In other cases probably not, due to Python scoping quirks!).
For on illustration of the scoping gotcha, try to instantiate Foo:
class Foo(object):
class Bar(object):
def __init__(self):
self.baz = Bar.baz
baz = 15
def __init__(self):
self.bar = Foo.Bar()
(It's going to complain about the global name 'Bar' not being defined.)
Also, something tells me you may want to look into class methods: docs on the classmethod function (to be used as a decorator), a relevant SO question. Edit: Ok, so this suggestion may not be appropriate at all... It's just that the first thing I thought about when reading your question was stuff like alternative constructors etc. If something simpler suits your needs, steer clear of #classmethod weirdness. :-)
Most code in the class will be inside method definitions, in which case you can simply use the name A.
This is how it works for me:
class SomeName:
def __init__(self):
self.value = "something"
def some_method(self):
print self.value
def external_func(instance, method):
method(instance)
external_func(SomeName(), SomeName.some_method)
This appears to work correctly. Is this the right way to do this?
Your code is "technically correct" (it does what you ask for) but - at least in your example - pretty useless:
def external_func(instance, method):
method(instance)
external_func(SomeName(), SomeName.some_method)
is the same as:
def external_func(method):
method()
external_func(SomeName().some_method)
which FWIW is the same as:
SomeName().some_method()
but I assume you understood this already .
Now you probably have a reason to try to pass both the method AND instance to external_func(), or there might be a better way to solve your real problem...
I of course don't know what you're doing exactly, but it sounds to me like you're trying to do too much inside of one function. Your problem might be better solved by simply splitting up the contents of external_func.
The goals here, as I understand them, are you don't know ahead of time what the object/method pair will be, and want to reduce code repetition.
Perhaps something like this would be better:
def main():
obj = SomeName()
# do the setting up portion
complex_object = external_func_set_up(obj)
# presumably at some point you have to designate the method to be used:
method = get_method_name(obj)
# run the method:
getattr(obj, method)()
# finish up the external operation:
external_func_complete(***args***)
I understand this is more code, but I think in the end it's a lot clearer what is happening, and also might force you to think through your problem a bit more (and potentially come up with an even better solution).
You could pass SomeName().some_method or make some_metod staticmethod or classmethod if there is no instance data used in your method.
Check documentation to know more about staticmethod and classmethod:
https://docs.python.org/3/library/functions.html#staticmethod
https://docs.python.org/3/library/functions.html#classmethod
Depending on what you're doing. Because functions are also objects in Python it is possible to do so.
But is it a good solution? It seems though that you're trying to handle a problem which maybe could be better solved with more of an object oriented approach:
class A:
def __init__(self):
self.value = "class A"
def some_method(self):
print self.value
class B:
def __init__(self):
self.value = "class B"
def some_method(self):
print self.value
some_class = A()
some_class.some_method()
some_class = B()
some_class.some_method()
Output:
"class A"
"class B"
In my view this would be a better approach (if this is possible/reasonable in your case): You just call some_method() on your class, maybe without even knowing what exact type of object you're dealing with (regarding inheritance). The class itself knows what to do and reacts accordingly when its method has been called.
This of course doesn't work when you work with external libraries which you have no influence on.
Here's my idea: Start with a simple object:
class dynamicObject(object):
pass
And to be able to add pre written methods to it on the fly:
def someMethod(self):
pass
So that I can do this:
someObject = dyncamicObject()
someObject._someMethod = someMethod
someObject._someMethod()
Problem is, it wants me to specify the self part of _someMethod() so that it looks like this:
someObject._someMethod(someObject)
This seems kind of odd since isn't self implied when a method is "attached" to an object?
I'm new to the Python way of thinking and am trying to get away from the same thought process for languages like C# so the idea here it to be able to create an object for validation by picking and choosing what validation methods I want to add to it rather than making some kind of object hierarchy. I figured that Python's "self" idea would work in my favor as I thought the object would implicitly know to send itself into the method attached to it.
One thing to note, the method is NOT attached to the object in any way (Completely different files) so maybe that is the issue? Maybe by defining the method on it's own, self is actually the method in question and therefore can't be implied as the object?
Although below I've tried to answer the literal question, I think
Muhammad Alkarouri's answer better addresses how the problem should actually be solved.
Add the method to the class, dynamicObject, rather than the object, someObject:
class dynamicObject(object):
pass
def someMethod(self):
print('Hi there!')
someObject=dynamicObject()
dynamicObject.someMethod=someMethod
someObject.someMethod()
# Hi there!
When you say someObject.someMethod=someMethod, then someObject.__dict__ gets the key-value pair ('someMethod',someMethod).
When you say dynamicObject.someMethod=someMethod, then someMethod is added to dynamicObject's __dict__. You need someMethod defined in the class for
someObject.someMethod to act like a method call. For more information about this, see Raymond Hettinger's essay on descriptors -- after all, a method is nothing more than a descriptor! -- and Shalabh Chaturvedi's essay on attribute lookup.
There is an alternative way:
import types
someObject.someMethod=types.MethodType(someMethod,someObject,type(someObject))
but this is really an abomination since you are defining 'someMethod' as a key in someObject.__dict__, which is not the right place for methods. In fact, you do not get a class method at all, just a curried function. This is more than a mere technicality. Subclasses of dynamicObject would fail to inherit the someMethod function.
To achieve what you want (create an object for validation by picking and choosing what validation methods I want to add to it), a better way is:
class DynamicObject(object):
def __init__(self, verify_method = None):
self.verifier = verify_method
def verify(self):
self.verifier(self)
def verify1(self):
print "verify1"
def verify2(self):
print "verify2"
obj1 = DynamicObject()
obj1.verifier = verify1
obj2 = DynamicObject(verify2)
#equivalent to
#obj2 = DynamicObject()
#obj2.verify = verify2
obj1.verify()
obj2.verify()
Why don't you use setattr? I found this way much more explicit.
class dynamicObject(object):
pass
def method():
print "Hi"
someObject = dynamicObject()
setattr(someObject,"method", method)
someObject.method()
Sometimes it is annoying to need to write a regular function and add it afterwards when the method is very simple. In that case, lambdas can come to the rescue:
class Square:
pass
Square.getX = lambda self: self.x
Square.getY = lambda self: self.y
Square.calculateArea = lambda self: self.getX() * self.getY()
Hope this helps.
If you just want to wrap another class, and not have to deal with assigning a new method to any instance, you can just make the method in question a staticmethod of the class:
class wrapperClass(object):
#staticmethod
def foo():
print("yay!")
obj = wrapperClass()
obj.foo() // Yay!
And you can then give any other class the .foo method with multiple inheritance.
class fooDict(dict, wrapperClass):
"""Normal dict with foo method"""
foo_dict = fooDict()
foo_dict.setdefault('A', 10)
print(foo_dict) // {'A': 10}
foo_dict.foo() // Yay!