I'm wondering if someone have a concrete use of __init__ function which is not the same as a constructor.
Because I'm reading everywhere that this should not considered as a constructor, but i can't find any example taking advantage of this or really showing why it is so important.
So if someone have some concrete code showing it, i would be glad to see that !
Thank you
__init__() isn't a constructor per se because __init__() isn't necessarily always called when attempting to construct an object:
class C(object):
def __new__(cls):
return 5
def __init__(self):
print 'I am a crow! CAW! CAW!'
c = C()
print c
Class Example:
def __init__(self,value1,value2):
self.value1 = value1
self.value2 = value2
I am not an expert at python, and admit that the init function might have other uses, but to me it looks like, and acts like a constructor.
also by definition, its a constructor:
Dictionary.com - Constructor
scroll to bottom of link for computer related definition
http://docs.python.org/2/reference/datamodel.html
scroll down to classic classes, there it says that a class can exist without an init method, so the init initializes some stuff for the class, but at the moment the init is called, the object already exists. Or thats at least what i understand of it, since otherwise it would probably be more logical to name it __constr__ or so, instead of __init__
Not really an answer to your question i guess, but you can in some cases just not use init, (if you consider "not using it" as a use for it, than i did answer part of the question?)
Related
I'm trying to define a class whose attributes are (mostly) provided by its users on instantiation. (There's more functionality to it, but this is what matters for the question.) My approach so far has been to pass keyword arguments to __init__ and then these kwargs are transformed into attributes (pretty much the same as argparse.Namespace).
It can be boiled down to this:
class Bag:
def __init__(self, **kwargs):
vars(self).update(kwargs)
And then it's used like this:
b = Bag(a=some_function, b=2)
This works as expected, the problem is that IDEs have no chance to provide autocomplete suggestions and that makes it less comfortable to use.
The question is if it's possible to somehow propagate the types of the passed arguments to the Bag instance itself (obviously only when this call can be analyzed statically). Or, if there's a more elegant alternative.
Thanks a lot in advance.
EDIT:
A hacky alternative I came up with was to use a class declaration with a metaclass to provide my extra functionality, and then use the class as if it was an object. Something like this:
class some_bag(metaclass=MagicBag):
a = "hello"
b = 2
some_bag.a # <-- recognized by the IDE
(This has however its own share of problems)
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.
Please excuse me, I'm new to Python and trying to learn the Pythonic approach. I'm designing a class that essentially initializes its state from a number of different sources (files). I've isolated this behavior to a single instance method, _load_from_file(file). It's called a number of times in __init__, but I typically like to keep my constructors at the beginning of a class definition, and my internal helper methods towards the end.
However, if I were to take this approach, _load_from_file isn't defined at the point in __init__ where I'd like to use it. How do you pythonistas lay this situation out?
To elaborate:
class Thing(object):
def __init__(self, file_path):
f = open('file_path')
_load_from_file(self,"someData",f) # ISSUES!
_load_from_file(self,"moreData",f) # WRONG!
f.close()
# Interface
# ...
# Internal - Where do you guys put this stuff?
def _load_from_file(self,thingToLoad,file):
# logic
Are you sure it won't work in the order you're already using? Remember, you're not using C. The called method doesn't have to appear in the class definition before calling code, so long as it has been defined by the time it gets called.
I would, however, change this:
_load_from_file(self)
to this:
self._load_from_file()
Any name-not-defined error you were getting was not because your method call was at a file position earlier than the method's definition, but because you tried to call it like a global function instead of via an object on which the method is defined.
I was wondering if anyone knew of a particular reason (other than purely stylistic) why the following languages these syntaxes to initiate a class?
Python:
class MyClass:
def __init__(self):
x = MyClass()
Ruby:
class AnotherClass
def initialize()
end
end
x = AnotherClass.new()
I can't understand why the syntax used for the constructor and the syntax used to actually get an instance of the class are so different. Sure, I know it doesn't really make a difference but, for example, in ruby what's wrong with making the constructor "new()"?
When you are creating an object of a class, you are doing more than just initializing it. You are allocating the memory for it, then initializing it, then returning it.
Note also that in Ruby, new() is a class method, while initialize() is an instance method. If you simply overrode new(), you would have to create the object first, then operate on that object, and return it, rather than the simpler initialize() where you can just refer to self, as the object has already been created for you by the built-in new() (or in Ruby, leave self off as it's implied).
In Objective-C, you can actually see what's going on a little more clearly (but more verbosely) because you need to do the allocation and initialization separately, since Objective-C can't pass argument lists from the allocation method to the initialization one:
[[MyClass alloc] initWithFoo: 1 bar: 2];
Actually in Python the constructor is __new__(), while __init__() is instance initializer.
__new__() is static class method, thus it has to be called first, as a first parameter (usually named cls or klass) it gets the class . It creates object instance, which is then passed to __init__() as first parameter (usually named self), along with all the rest of __new__'s parameters.
This is useful because in Python, a constructor is just another function. For example, I've done this several times:
def ClassThatShouldntBeDirectlyInstantiated():
return _classThatShouldntBeDirectlyInstantiated()
class _classThatShouldntBeDirectlyInstantiated(object):
...
Of course, that's a contrived example, but you get the idea. Essentially, most people that use your class will probably think of ClassThatShouldntBeDirectlyInstantiated as your class, and there's no need to let them think otherwise. Doing things this way, all you have to do is document the factory function as the class it instantiates and not confuse anyone using the class.
In a language like C# or Java, I sometimes find it annoying to make classes like this because it can be difficult to determine whether you should use the constructor or some factory function. I'm not sure if this is also the case in Ruby though.
I would like to make a child class that has a method of the parent class where the method is a 'classmethod' in the child class but not in the parent class.
Essentially, I am trying to accomplish the following:
class foo(Object):
def meth1(self, val):
self.value = val
class bar(foo):
meth1 = classmethod(foo.meth1)
I'm also not entirely sure what the exact behaviour you want is, but assuming its that you want bar.meth1(42) to be equivalent to foo.meth1 being a classmethod of bar (with "self" being the class), then you can acheive this with:
def convert_to_classmethod(method):
return classmethod(method.im_func)
class bar(foo):
meth1 = convert_to_classmethod(foo.meth1)
The problem with classmethod(foo.meth1) is that foo.meth1 has already been converted to a method, with a special meaning for the first parameter. You need to undo this and look at the underlying function object, reinterpreting what "self" means.
I'd also caution that this is a pretty odd thing to do, and thus liable to cause confusion to anyone reading your code. You are probably better off thinking through a different solution to your problem.
What are you trying to accomplish? If I saw such a construct in live Python code, I would consider beating the original programmer.
The question, as posed, seems quite odd to me: I can't see why anyone would want to do that. It is possible that you are misunderstanding just what a "classmethod" is in Python (it's a bit different from, say, a static method in Java).
A normal method is more-or-less just a function which takes as its first argument (usually called "self"), an instance of the class, and which is invoked as ".".
A classmethod is more-or-less just a function which takes as its first argument (often called "cls"), a class, and which can be invoked as "." OR as ".".
With this in mind, and your code shown above, what would you expect to have happen if someone creates an instance of bar and calls meth1 on it?
bar1 = bar()
bar1.meth1("xyz")
When the code to meth1 is called, it is passed two arguments 'self' and 'val'. I guess that you expect "xyz" to be passed for 'val', but what are you thinking gets passed for 'self'? Should it be the bar1 instance (in this case, no override was needed)? Or should it be the class bar (what then would this code DO)?