Do I add my functions for a module into a class? - python

I'm working on a function library/module for a project. I was wondering, to use it in another file as a module, do I need to put it in a class? I've tried adding my module to other files, but it doesn't work. Also, a lot of other built-in modules are in a class. Should I put it in a class or not? I'm also looking for an objective answer and not if it's a common practice or not.

You can put it in a class or let it outside a class. It depends on the use of this function.
e.g.:
class MyClass:
#staticmethod
def function(arguments):
# Your code
In order to import it you will have to use this:
from name_of_the_file import name_of_the_class
In the file you will have to use name_of_the_class.name_of_the_function().
e.g.:
MyClass.function(arguments)
If you define the function outside a class:
from name_of_the_file import name_of_the_function

In general, you don't need to put functions in a class. For example, functools.wraps() is a function.
However, you haven't mentioned the actual problem you're having, so this general answer is probably not very helpful.

Related

How do I take functions that I already made to run a program and put them under a class?

I am making a contact list system for a class project and used tkinter to make my gui and sqlite3 for the database. I made a bunch of methods that have basically solved the problem but I noticed the question paper says that the functions need to be in a class. How do I put these functions under a class without messing everything up. I am using python3.
A function in a module is similar to a static method in a class. Without knowing any of your app's specifics:
If you have a function that does what you want
def f():
return 'g'
and you want to encapsulate it in a class
class Q:
pass
just assign it as a static method to that class
Q.f = staticmethod(f)
Whenever you need to use that function you have to call it via the class
>>> Q.f()
g
This is similar to what happens when you import a module that has functions - you import the module and call the functions using the module name (the functions are module attributes) - modulename.func().
I really have no idea how this fits with your need or what any downsides might be.

How to convert a "custom class"-based singleton object programmatically into a python module?

I would like to convert a singleton-object programmatically into a Python module so that I can use the methods of this singleton-object directly by importing them via the module instead of accessing them as object attributes. By "programmatically" I mean that I do not want to have to copy-paste the class methods explicitly into a module file. I need some sort of a workaround that allows me to import the object methods into to global scope of another module.
I would really appreciate if someone could help me on this one.
Here is a basic example that should illustrate my problem:
mymodule.py
class MyClass:
"""This is my custom class"""
def my_method(self):
return "myValue"
singleton = MyClass()
main_as_is.py
from mymodule import MyClass
myobject = MyClass()
print(myobject.my_method())
main_to_be.py
from mymodule import my_method # or from mymodule.singleton import my_method
print(my_method())
You can use the same strategy that the standard random module uses. All the functions in that module are actually methods of a "private" instance of the Random class. That's convenient for most common uses of the module, although sometimes it's useful to create your own instances of Random so that you can have multiple independent random streams.
I've adapted your code to illustrate that technique. I named the class and its instance with a single leading underscore, since that's the usual convention in Python to signify a private name, but bear in mind it's simply a convention, Python doesn't do anything to enforce this privacy.
mymodule.py
class _MyClass:
""" This is my custom class """
def my_method(self):
return "myValue"
_myclass = _MyClass()
my_method = _myclass.my_method
main_to_be.py
from mymodule import my_method
print(my_method())
output
myValue
BTW, the from mymodule import method1, method2 syntax is ok if you only import a small number of names, or it's clear from the name which module it's from (like math module functions and constants), and you don't import from many modules. Otherwise it's better to use this sort of syntax
import mymodule as mm
# Call a method from the module
mm.method1()
That way it's obvious which names are local, and which ones are imported and where they're imported from. Sure, it's a little more typing, but it makes the code a whole lot more readable. And it eliminates the possibility of name collisions.
FWIW, here's a way to automate adding all of the _myclass methods without explicitly listing them (but remember "explicit is better than implicit"). At the end of "mymodule.py", in place of my_method = _myclass.my_method, add this:
globals().update({k: getattr(_myclass, k) for k in _MyClass.__dict__
if not k.startswith('__')})
I'm not comfortable with recommending this, since it directly injects items into the globals() dict. Note that that code will add all class attributes, not just methods.
In your question you talk about singleton objects. We don't normally use singletons in Python, and many programmers in various OOP languages consider them to be an anti-pattern. See https://stackoverflow.com/questions/12755539/why-is-singleton-considered-an-anti-pattern for details. For this application there is absolutely no need at all to use a singleton. If you only want a single instance of _MyClass then simply don't create another instance of it, just use the instance that mymodule creates for you. But if your boss insists that you must use a singleton, please see the example code here.

How to make a python class not exposed to the outside?

I'm relatively new to Python.
When I did C/C++ programming, I used the internal classes quite often. For example, in some_file.cc, we may implement a class in the anonymous namespace to prevent it from being used outside. This is useful as a helper class specific to that file.
Then, how we can do a similar thing in Python?
class MyClassOuter:
def __init__(self,...):
class MyClassInner:
def __init__(self,...):
pass
self.my_class = MyClassInner(..)
would only have MyClassInner available inside the __init__ function of MyClassOuter
likewise you could put it inside a function
def my_class_factory(arg1,arg2,...):
class MyClass:
def __init__(self,arg1,arg2,...):
print "OK??"
return MyClass(arg1,arg2,...)
Python code doesn't have any such equivalent for an anonymous namespace, or static linkage for functions. There are a few ways you can get what you're looking for
Prefix with _. Names beginning with an underscore are understood
to be for internal use to that python file and are not exported by
from * imports. it's as simple as class _MyClass.
Use __all__: If a python file contains a list a list of strings
named __all__, the functions and classes named within are
understood to be local to that python file and are not exported by
from *.
Use local classes/functions. This would be done the same way you've
done so with C++ classes.
None these gets exactly what you want, but privacy and restricting in this way are just not part of the language (much like how there's no private data member equivalent). Pydoc is also well aware of these conventions and will provide informative documentation for the intended-to-be-public functions and classes.

Is it possible to avoid writing 'dot' each time when calling class method?

Sorry for somewhat unclear question. I'm actually wondering whether it's possible in Python not to mention class name, when you call class's methods iteratively? I mean to write instead of:
SomeClass.Fun1()
SomeClass.Fun2()
...
SomeClass.Fun100()
Something like:
DoWith SomeClass:
Fun1()
Fun2()
...
Fun100()
?
There are several methods to achieve that (from SomeClass import *, locals().update(SomeClass.__dict__())), but what you're trying is not really logical:
In 90% of cases you're not calling static class methods, but member functions, which need a single instance to operate on. You do realize that the first, the self argument that you typically see on methods is important, because it gives you access to the instance's namespace. So even in methods, you use self.my_member instead of my_member. That's an important python concept, and you should not try to avoid it -- there's a difference between the local name space and the attributes of an instance.
What you can do, however, is having a short handle, without any overhead:
my_instance = SomeClass() #notice, this is an instance of SomeClass, not the class or type itself
__ = my_instance
that can save you a lot of typing. But I prefer clarity over saved typing (hell, vim has good autocompletion plugins for Python).
yes, just try from SomeClass import * (after moving SomeClass to an other file of course)

returning another class when instantiating a class in python

I am trying to use logging's memory handler to buffer log messages to my actual logging handler. You use the memory handler by instantiating it with some arguments, like this:
import logging
buffered_handler = logging.handlers.MemoryHandler(capacity=5,target=myActualHandler)
However, I don't want my application to have to instantiate a handler from logging directly, or pass any of the arguments; I'd like this code to look like this:
import myhandlers
buffered_handler = myhandlers.BufferedRemoteHandler()
The question is: how do I do this? I'd like an attempt to instantiate my BufferedRemoteHandler to actually return logging's MemoryHandler with some specific arguments. I thought of just making BufferedRemoteHandler a function which returns the handler I want; is that the correct way? Is there a way to create a class which, when you instantiate it, actually returns a totally different class?
Maybe point 3 of PEP 8 is the answer:
Simple is better than complex.
I'd go the function way. Maybe call it something like get_handler() (or get_buffered_remote_handler()) though, so you realize it is something other than a real class at first glance.
To answer your exact question, you may, if you like, override __new__() on your subclass to return an instance of a class other than yours.
import logging
class BufferedRemoteHandler(object):
def __new__(cls):
return logging.handlers.MemoryHandler(capacity=5,target=myActualHandler)
But I'd actually suggest the function.
Yes just make it a function. Something like getMemoryHandler(). THat's the best way to do it. Also, if only one instance of MemoryHandler is going to be around you may want to make it a singleton.
Well, to answer you directly, yes, there's __new__(). However, I think what would probably be an easier solution would be to either hard code or allow special handler definitions to be registered to myhandlers. You'd define a member method for each handler you want in myhandlers that just instantiated the MemoryHandler as you want and returned it.

Categories