python - Why do classes with no constructor arguments need parenthesis -
i started off learning programming/oop in php. best of knowledge of best practices in php, can instantiate class without parenthesis if not take arguments.
such
$class = new class;
as opposed to:
$class = new class();
i starting expand skills python , wasted 5 hours yesterday trying figure out why function wouldn't pass argument though ridiculously simple. code:
class mainviewwidgets(mainviewcontainer): def __init__(self): # instantiating prevents mainviewcontroller.getheaderitems returning arg passed it, code still "works" in sense self.controller = mainviewcontroller #this works self.controller = mainviewcontroller() def createheaderoptioncheckbox(self, pane): self.header_string = stringvar() header_checkbox = ttk.checkbutton(pane, text='data contains headers', variable=self.header_string, onvalue='headers', offvalue='keys') self.header_string.trace('w', self.headeroptioncheckboxchanged) return header_checkbox def headeroptioncheckboxchanged(self, *args): print(self.header_string.get()) #will print "headers" or "keys" on checkbox toggle print(self.controller.getheaderitems(self.header_string.get())) #prints "default" class mainviewcontroller: def __init__(self): self.checkfile = checkfile() get_config = getconfiguration('config.ini') self.config_file = get_config.getproperty('directory', 'input_file') self.csv = csvreader(self.config_file) self.chosen_index = none def getheaderitems(self, header='default'): return header
can please me understand why in python need instantiate class parenthesis if there no constructor arguments other self
. also, why did mainviewcontroller
still kind of work, did not behave wanted to? in loaded, , functions "did things", not seem accept arguments. there advantages of instantiating class without parenthesis?
please note, not need getting code work, want understand why happens.
can please me understand why in python need instantiate class parenthesis if there no constructor arguments other self.
the reason simple: when instantiate object, calling class (which object), , call objects using ()
.
in python, everything first-class object, classes (and functions!) themselves. in order class first class object, follows class needs own class (metaclass) define behavior. call class of class "metaclass" avoid confusion when talking classes , classes of classes.
to answer second part of question: "things" happening when used mainviewcontroller
instead of mainviewcontroller()
because mainviewcontroller
is full-fledged object, other object.
so might ask: class - metaclass - of mainviewcontroller
object?
as know, can create class this:
class myclass: pass
when this, in actuality creating new instance of metaclass known type
.
note can create same class way; there literally no difference between below , above:
myclass = type('myclass', (object,), {})
the type
metaclass base metaclass of classes. python "new style classes" (not "new" anymore since implemented in python 2.1, believe) of class type
:
print(type(myclass)) # type print(type(list)) # type print(type(int)) # type # note above, type being used "function" (it's callable)
interestingly enough, type
own metaclass:
print(type(type)) # type
so reiterate: class myclass
instantiation of type
. follows, then, calling class results in running __call__
method of metaclass.
when do:
obj = myclass()
...you calling myclass
, results (in background) in running method type.__call__()
.
this case user defined classes, btw; if include __call__
method in class, class callable, , __call__
method executed when call class instances:
class mycallable(): def __call__(self): print("you rang?") my_instance = mycallable() my_instance() # rang?
you can see in action. if create own metaclass subclassing type
, can cause things happen when instance of class based on custom metaclass created. example:
class mymeta(type): def __call__(self, *args, **kwargs): print "call: {} {} {}".format(self, args, kwargs) return super().__call__(*args, **kwargs) # python 3: class myclass(metaclass = mymeta): pass # python 2: class myclass(): __metaclass__ = mymeta pass
now when myclass()
, can see __call__
method of mymeta
happens before else (including before __new__
, before __init__
).
Comments
Post a Comment