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

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -