Are classes necessary for creating methods (defs) in Python? - python

Are classes necessary for creating methods (defs) in Python?

No. However, def's which aren't part of a class are usually called functions, not methods - but they are exactly the same thing, aside from not being associated with a class.
def myFunction(arg1, arg2):
# do something here

No, you can create functions using def without having to wrap them in classes.
If you are coming from a Java or C# background - where a class is required - you may want to read over An Introduction to Python: Functions or a similar article to understand how to work with functions in Python, as the language provides many other features such as first-class functions, returning multiple values, anonymous functions, etc.

It depends on your definition of "method".
In some sense, no, classes aren't necessary for creating methods in Python, because there are no methods anyway in Python. There are only procedures (which, for some strange reason, are called functions in Python). You can create a procedure anywhere you like. A method is just syntactic sugar for a procedure assigned to an attribute.
In another sense, yes, classes are necessary for creating methods. It follows pretty much from the definition of what a method is in Python: a procedure stuck into a class's __dict__. (Note, however, that this means that you do not have to be inside a class definition to create method, you can create a procedure anywhere and any way you like and stick it into the class afterwards.)
[Note: I have simplified a bit when it comes to exactly what a method is, how they are synthesized, how they are represented and how you can create your own.]

Related

Code design: Instance method with deeply nested conditionals, put in another instance method of the same class or put it in a function?

Suppose I have an instance method that contains a lot of nested conditionals. What would be a good way to encapsulate that code? Put in another instance method of the same class or a function? Could you say why a certain approach is preferred?
If the function is only used by one class, and especially if the module has more classes with potentially more utility functions (used only by one class), it might clarify things a bit if you kept the functions as static methods instead to make it obvious which class they belong to. Also, automated refactorings (using the e.g. the rope library, or PyCharm or PyDev etc) then automatically move the static method along with the class to wherever the class is moved.
P.S. #staticmethods, unlike module-level functions, can be overridden in subclasses, e.g. in case of a mathematical formula that doesn't depend on the object but does depend on the type of the object.
There are two different questions here. The first one is what to do with multiple nested conditionals. There's no single right answer: it depends on your coding style, how the conditions interact, the architecture of your program and so on. Have a look at this Programmers.SE question and Jeff Atwood's blog post for some ideas; personally, I like
if not check1: return
code1
if not check2: return
code 2
...
although some people object to the multiple exit points.
The second question is what to do with individual functions if you're writing object oriented Python. The usual answer is just to put them as functions inside the module containing the class, since there's no requirement that a function be attached to a particular class. If you want, though, you can include them in the class as static methods.

When should I use a class and when should I use a function?

When is a class more useful to use than a function? Is there any hard or fast rule that I should know about? Is it language dependent? I'm intending on writing a script for Python which will parse different types of json data, and my gut feeling is that I should use a class to do this, versus a function.
You should use a class when your routine needs to save state. Otherwise a function will suffice.
First of all, I think that isn't language-dependent (if the language permit you to define classes and function as well).
As a general rule I can tell you that a Class wrap into itself a behaviour. So, if you have a certain type of service that you have to implement (with, i.e. different functions) a class is what you're lookin' for.
Moreover classes (say object that is more correct) has state and you can instantiate more occurrences of a class (so different objects with different states).
Not less important, a class can be inearthed: so you can overwrite a specific behaviour of your function only with small changes.
the class when you have the state - something that should be persistent across the calls
the function in other cases
exception: if your class is only storing couple of values and has a single method besides __init__, you should better use the function
For anything non-trivial, you should probably be using a class. I tend to limit all of my "free-floating" functions to a utils.py file.
This is language-dependent.
Some languages, like Java, insist that you use a class for everything. There's simply no concept of a standalone function.
Python isn't like that. It's perfectly OK - in fact recommended - to define functions standalone, and related functions can be grouped together in modules. As others have stated, the only time you really want a class in Python is when you have state that you need to keep - ie, encapsulating the data within the object.

Why do we want to pass a Class to a function

As Classes are first-class objects in Python, we can pass them to functions. For example, here is some code I've come across:
ChatRouter = sockjs.tornado.SockJSRouter(ChatConnection, '/chat')
where ChatConnection is a Class defined in the same module. I wonder what would be the common user case(s) for such practice?
In addition, in the code example above, why is the variable 'ChatRouter' capitalized?
Without knowing anything else about that code, I'd guess this:
OK, I looked at the source. Below the line is incorrect, although plausible. Basically what the code does is use ChatConnection to create a Session object which does some other stuff. ChatRouter is just a badly named regular variable, not a class name.
SockJSRouter is a class that takes another class (call it connection) and a string as parameters. It uses __new__ to create not an instance of SockJSRouter, but an instance of a special class that uses (possibly subclasses) connection. That would explain why ChatRouter is capitalized, as it would be a class name. The returned class would use connection to generalize a lot of things, as connection would be responsible for handling communicating over a network or whatever. So by using different connections, one could handle different protocols. ChatConnection is probably some layer over IRC.
So basically, the common use case (and likely the use here) is generalization, and the reason for the BactrianCase name is because it's a class (just one generated at runtime).
Passing classes around may be useful for customization and flexible code. The function may want to create several objects of the given class, so passing it a class is one way to implement this (another would be to pass some kind of factory function). For example, in the example you gave, SockJSRouter ends up passing the connection class to Session, which then uses it to construct a new connection object.
As for ChatRouter, I suppose this is just a naming convention. While Python programmers are advised to follow PEP 8, and many do, it's not strictly required and some projects settle on different naming conventions.

What is Ruby's analog to Python Metaclasses?

Python has the idea of metaclasses that, if I understand correctly, allow you to modify an object of a class at the moment of construction. You are not modifying the class, but instead the object that is to be created then initialized.
Python (at least as of 3.0 I believe) also has the idea of class decorators. Again if I understand correctly, class decorators allow the modifying of the class definition at the moment it is being declared.
Now I believe there is an equivalent feature or features to the class decorator in Ruby, but I'm currently unaware of something equivalent to metaclasses. I'm sure you can easily pump any Ruby object through some functions and do what you will to it, but is there a feature in the language that sets that up like metaclasses do?
So again, Does Ruby have something similar to Python's metaclasses?
Edit I was off on the metaclasses for Python. A metaclass and a class decorator do very similar things it appears. They both modify the class when it is defined but in different manners. Hopefully a Python guru will come in and explain better on these features in Python.
But a class or the parent of a class can implement a __new__(cls[,..]) function that does customize the construction of the object before it is initialized with __init__(self[,..]).
Edit This question is mostly for discussion and learning about how the two languages compare in these features. I'm familiar with Python but not Ruby and was curious. Hopefully anyone else who has the same question about the two languages will find this post helpful and enlightening.
Ruby doesn't have metaclasses. There are some constructs in Ruby which some people sometimes wrongly call metaclasses but they aren't (which is a source of endless confusion).
However, there's a lot of ways to achieve the same results in Ruby that you would do with metaclasses. But without telling us what exactly you want to do, there's no telling what those mechanisms might be.
In short:
Ruby doesn't have metaclasses
Ruby doesn't have any one construct that corresponds to Python's metaclasses
Everything that Python can do with metaclasses can also be done in Ruby
But there is no single construct, you will use different constructs depending on what exactly you want to do
Any one of those constructs probably has other features as well that do not correspond to metaclasses (although they probably correspond to something else in Python)
While you can do anything in Ruby that you can do with metaclasses in Python, it might not necessarily be straightforward
Although often there will be a more Rubyish solution that is elegant
Last but not least: while you can do anything in Ruby that you can do with metaclasses in Python, doing it might not necessarily be The Ruby Way
So, what are metaclasses exactly? Well, they are classes of classes. So, let's take a step back: what are classes exactly?
Classes …
are factories for objects
define the behavior of objects
define on a metaphysical level what it means to be an instance of the class
For example, the Array class produces array objects, defines the behavior of arrays and defines what "array-ness" means.
Back to metaclasses.
Metaclasses …
are factories for classes
define the behavior of classes
define on a metaphysical level what it means to be a class
In Ruby, those three responsibilities are split across three different places:
the Class class creates classes and defines a little bit of the behavior
the individual class's eigenclass defines a little bit of the behavior of the class
the concept of "classness" is hardwired into the interpreter, which also implements the bulk of the behavior (for example, you cannot inherit from Class to create a new kind of class that looks up methods differently, or something like that – the method lookup algorithm is hardwired into the interpreter)
So, those three things together play the role of metaclasses, but neither one of those is a metaclass (each one only implements a small part of what a metaclass does), nor is the sum of those the metaclass (because they do much more than that).
Unfortunately, some people call eigenclasses of classes metaclasses. (Until recently, I was one of those misguided souls, until I finally saw the light.) Other people call all eigenclasses metaclasses. (Unfortunately, one of those people is the author of one the most popular tutorials on Ruby metaprogramming and the Ruby object model.) Some popular libraries add a metaclass method to Object that returns the object's eigenclass (e.g. ActiveSupport, Facets, metaid). Some people call all virtual classes (i.e. eigenclasses and include classes) metaclasses. Some people call Class the metaclass. Even within the Ruby source code itself, the word "metaclass" is used to refer to things that are not metaclasses.
Your updated question looks quite different now. If I understand you correctly, you want to hook into object allocation and initialization, which has absolutely nothing whatsoever to do with metaclasses. (But you still don't write what it is that you actually want to do, so I might still be off.)
In some object-oriented languages, objects are created by constructors. However, Ruby doesn't have constructors. Constructors are just factory methods (with stupid restrictions); there is no reason to have them in a well-designed language, if you can just use a (more powerful) factory method instead.
Object construction in Ruby works like this: object construction is split into two phases, allocation and initialization. Allocation is done by a public class method called allocate, which is defined as an instance method of class Class and is generally never overriden. (In fact, I don't think you actually can override it.) It just allocates the memory space for the object and sets up a few pointers, however, the object is not really usable at this point.
That's where the initializer comes in: it is an instance method called initialize, which sets up the object's internal state and brings it into a consistent, fully defined state which can be used by other objects.
So, in order to fully create a new object, what you need to do is this:
x = X.allocate
x.initialize
[Note: Objective-C programmers may recognize this.]
However, because it is too easy to forget to call initialize and as a general rule an object should be fully valid after construction, there is a convenience factory method called Class#new, which does all that work for you and looks something like this:
class Class
def new(*args, &block)
obj = allocate
obj.initialize(*args, &block)
return obj
end
end
[Note: actually, initialize is private, so reflection has to be used to circumvent the access restrictions like this: obj.send(:initialize, *args, &block)]
That, by the way, is the reason why to construct an object you call a public class method Foo.new but you implement a private instance method Foo#initialize, which seems to trip up a lot of newcomers.
However, none of this is in any way baked into the language. The fact that the primary factory method for any class is usually called new is just a convention (and sometimes I wish it were different, because it looks similar to constructors in Java, but is completely different). In other languages, the constructor must have a specific name. In Java, it must have the same name as the class, which means that a) there can be only one constructor and b) anonymous classes can't have constructors because they don't have names. In Python, the factory method must be called __new__, which again means there can be only one. (In both Java and Python, you can of course have different factory methods, but calling them looks different from calling the default, while in Ruby (and Smalltalk from whence this pattern originated) it looks just the same.)
In Ruby, there can be as many factory methods as you like, with any name you like, and a factory method can have many different names. (For collection classes, for example, the factory method is often aliased to [], which allows you to write List[1, 2, 3] instead of List.new(1, 2, 3) which ends looking more like an array, thus emphasizing the collection-ish nature of lists.)
In short:
the standardized factory method is Foo.new, but it can be anything
Foo.new calls allocate to allocate memory for an empty object foo
Foo.new then calls foo.initialize, i.e. the Foo#initialize instance method
all three of those are just methods like any other, which you can undefine, redefine, override, wrap, alias and whatnot
well, except allocate which needs to allocate memory inside the Ruby runtime which you can't really do from Ruby
In Python, __new__ roughly corresponds to both new and allocate in Ruby, and __init__ exactly corresponds to initialize in Ruby. The main difference is that in Ruby, new calls initialize whereas in Python, the runtime automatically calls __init__ after __new__.
For example, here is a class which only allows a maximum of 2 instances created:
class Foo
def self.new(*args, &block)
#instances ||= 0
raise 'Too many instances!' if #instances >= 2
obj = allocate
obj.send(:initialize, *args, &block)
#instances += 1
return obj
end
attr_reader :name
def initialize(name)
#name = name
end
end
one = Foo.new('#1')
two = Foo.new('#2')
puts two.name # => #2
three = Foo.new('#3') # => RuntimeError: Too many instances!

Which is more pythonic, factory as a function in a module, or as a method on the class it creates?

I have some Python code that creates a Calendar object based on parsed VEvent objects from and iCalendar file.
The calendar object just has a method that adds events as they get parsed.
Now I want to create a factory function that creates a calendar from a file object, path, or URL.
I've been using the iCalendar python module, which implements a factory function as a class method directly on the Class that it returns an instance of:
cal = icalendar.Calendar.from_string(data)
From what little I know about Java, this is a common pattern in Java code, though I seem to find more references to a factory method being on a different class than the class you actually want to instantiate instances from.
The question is, is this also considered Pythonic ? Or is it considered more pythonic to just create a module-level method as the factory function ?
[Note. Be very cautious about separating "Calendar" a collection of events, and "Event" - a single event on a calendar. In your question, it seems like there could be some confusion.]
There are many variations on the Factory design pattern.
A stand-alone convenience function (e.g., calendarMaker(data))
A separate class (e.g., CalendarParser) which builds your target class (Calendar).
A class-level method (e.g. Calendar.from_string) method.
These have different purposes. All are Pythonic, the questions are "what do you mean?" and "what's likely to change?" Meaning is everything; change is important.
Convenience functions are Pythonic. Languages like Java can't have free-floating functions; you must wrap a lonely function in a class. Python allows you to have a lonely function without the overhead of a class. A function is relevant when your constructor has no state changes or alternate strategies or any memory of previous actions.
Sometimes folks will define a class and then provide a convenience function that makes an instance of the class, sets the usual parameters for state and strategy and any other configuration, and then calls the single relevant method of the class. This gives you both the statefulness of class plus the flexibility of a stand-alone function.
The class-level method pattern is used, but it has limitations. One, it's forced to rely on class-level variables. Since these can be confusing, a complex constructor as a static method runs into problems when you need to add features (like statefulness or alternative strategies.) Be sure you're never going to expand the static method.
Two, it's more-or-less irrelevant to the rest of the class methods and attributes. This kind of from_string is just one of many alternative encodings for your Calendar objects. You might have a from_xml, from_JSON, from_YAML and on and on. None of this has the least relevance to what a Calendar IS or what it DOES. These methods are all about how a Calendar is encoded for transmission.
What you'll see in the mature Python libraries is that factories are separate from the things they create. Encoding (as strings, XML, JSON, YAML) is subject to a great deal of more-or-less random change. The essential thing, however, rarely changes.
Separate the two concerns. Keep encoding and representation as far away from state and behavior as you can.
It's pythonic not to think about esoteric difference in some pattern you read somewhere and now want to use everywhere, like the factory pattern.
Most of the time you would think of a #staticmethod as a solution it's probably better to use a module function, except when you stuff multiple classes in one module and each has a different implementation of the same interface, then it's better to use a #staticmethod
Ultimately weather you create your instances by a #staticmethod or by module function makes little difference.
I'd probably use the initializer ( __init__ ) of a class because one of the more accepted "patterns" in python is that the factory for a class is the class initialization.
IMHO a module-level method is a cleaner solution. It hides behind the Python module system that gives it a unique namespace prefix, something the "factory pattern" is commonly used for.
The factory pattern has its own strengths and weaknesses. However, choosing one way to create instances usually has little pragmatic effect on your code.
A staticmethod rarely has value, but a classmethod may be useful. It depends on what you want the class and the factory function to actually do.
A factory function in a module would always make an instance of the 'right' type (where 'right' in your case is the 'Calendar' class always, but you might also make it dependant on the contents of what it is creating the instance out of.)
Use a classmethod if you wish to make it dependant not on the data, but on the class you call it on. A classmethod is like a staticmethod in that you can call it on the class, without an instance, but it receives the class it was called on as first argument. This allows you to actually create an instance of that class, which may be a subclass of the original class. An example of a classmethod is dict.fromkeys(), which creates a dict from a list of keys and a single value (defaulting to None.) Because it's a classmethod, when you subclass dict you get the 'fromkeys' method entirely for free. Here's an example of how one could write dict.fromkeys() oneself:
class dict_with_fromkeys(dict):
#classmethod
def fromkeys(cls, keys, value=None):
self = cls()
for key in keys:
self[key] = value
return self

Categories