Bidirectional dependencies between classes causing issues - python-3.x

I have a class to represent a resource (for the sake of the example, let's say a folder), and a factory class to create those resources.
The issue is that, for clarity purposes, I wish to provide each folder with it's own factory, allowing it to generate it's sub-folders.
This currently looks like this :
folder.py
import FolderFactory
class Folder
def __init__(self):
self.file_factory = FolderFactory(self)
self.sub_folders = []
folder_factory.py
import File
class FolderFactory
def __init__(self, folder):
assert isinstance(folder, Folder)
self.folder = Folder(folder)
def create_sub_folder(name):
// Create Folder
self.folder.sub_folders.append(new_folder)
But obviously this generate a circular reference, which cause an error.
Is there an issue with my design, or is there a way to implement this cleanly ?
The end goal would be to be able to write something along the lines of
folder.folder_factory.create_folder("new")
Please note that the actual factory class I'm working with have a large amount of functions to generate different resources in the parent resource, which explains the need to separate the object definition and the management functions.
Thanks a lot for taking the time to read !

You could pass a self from the FolderFactory to the constructor of the folder, to be used as a reference to its 'parent'.
import FolderFactory
class Folder
def __init__(self, factory):
self.file_factory = FolderFactory(self)
self.folder_factory = factory
self.sub_folders = []
import File
class FolderFactory
def __init__(self, folder):
assert isinstance(folder, Folder)
self.folder = Folder(folder, self)
def create_sub_folder(name):
// Create Folder
self.folder.sub_folders.append(new_folder)

Related

python: multiple functions or abstract classes when dealing with data flow requirement

I have more of a design question, but I am not sure how to handle that. I have a script preprocessing.py where I read a .csv file of text column that I would like to preprocess by removing punctuations, characters, ...etc.
What I have done now is that I have written a class with several functions as follows:
class Preprocessing(object):
def __init__(self, file):
self.my_data = pd.read_csv(file)
def remove_punctuation(self):
self.my_data['text'] = self.my_data['text'].str.replace('#','')
def remove_hyphen(self):
self.my_data['text'] = self.my_data['text'].str.replace('-','')
def remove_words(self):
self.my_data['text'] = self.my_data['text'].str.replace('reference','')
def save_data(self):
self.my_data.to_csv('my_data.csv')
def preprocessing(file_my):
f = Preprocessing(file_my)
f.remove_punctuation()
f.remove_hyphen()
f.remove_words()
f.save_data()
return f
if __name__ == '__main__':
preprocessing('/path/to/file.csv')
although it works fine, i would like to be able to expand the code easily and have smaller classes instead of having one large class. So i decided to use abstract class:
import pandas as pd
from abc import ABC, abstractmethod
my_data = pd.read_csv('/Users/kgz/Desktop/german_web_scraping/file.csv')
class Preprocessing(ABC):
#abstractmethod
def processor(self):
pass
class RemovePunctuation(Preprocessing):
def processor(self):
return my_data['text'].str.replace('#', '')
class RemoveHyphen(Preprocessing):
def processor(self):
return my_data['text'].str.replace('-', '')
class Removewords(Preprocessing):
def processor(self):
return my_data['text'].str.replace('reference', '')
final_result = [cls().processor() for cls in Preprocessing.__subclasses__()]
print(final_result)
So now each class is responsible for one task but there are a few issues I do not know how to handle since I am new to abstract classes. first, I am reading the file outside the classes, and I am not sure if that is good practice? if not, should i pass it as an argument to the processor function or have another class who is responsible to read the data.
Second, having one class with several functions allowed for a flow, so every transformation happened in order (i.e, first punctuation is removes, then hyphen is removed,...etc) but I do not know how to handle this order and dependency in abstract classes.

Python Inheritance: Why does the Folder class inherit from the File class

The below code is from a book I'm reading related to OOP in Python 3. Can someone help me understand the logic of the below? It seems counterintuitive that the Folder class inherits from the File class. For example, in the below, when a Folder is instantiated, it seems that a File is also instantiated with the same name but in reality you would not want this to happen. What am I missing?
class File:
def __init__(self, name):
self.name = name
class Folder(File):
def __init__(self, name):
super().__init__(name)
self.children = []
root = Folder("")
etc = Folder("etc")
root.children.append(etc)
etc.children.append(File("passwd"))
etc.children.append(File("groups"))
httpd = Folder("httpd")
etc.children.append(httpd)
httpd.children.append(File("http.conf"))
var = Folder("var")
root.children.append(var)
log = Folder("log")
var.children.append(log)
log.children.append(File("messages"))
log.children.append(File("kernel"))

The best way to share a class between processes

First of all, I'm pretty new in multiprocessing and I'm here for learning of all of you. I have several files doing something similar to this:
SharedClass.py:
class simpleClass():
a = 0
b = ""
.....
MyProcess.py:
import multiprocessing
import SharedClass
class FirstProcess(multiprocessing.Process):
def __init__(self):
multiprocessing.Process.__init__(self)
def modifySharedClass():
# Here I want to modify the object shared with main.py defined in SharedClass.py
Main.py:
from MyProcess import FirstProcess
import sharedClass
if __name__ == '__main__':
pr = FirstProcess()
pr.start()
# Here I want to print the initial value of the shared class
pr.modifySharedClass()
# Here I want to print the modified value of the shared class
I want to define a shared class (in SharedClass.py), in a kind of shared memory that can be readed and writted for both files Main.py and MyProcess.py.
I have try to use the Manager of multiprocessing and multiprocessing.array but Im not having good results, the changes made in one file are not beeing reflected in the other file (maybe Im doing this in the wrong way).
Any ideas? Thank you.

Django move models classmethod to another file

I have model
Order(models.Model):
name = models.Charfield()
#classmethod
do_something(cls):
print('do soemthing')
What I want to do is to move do_something method from my model to another file.I want to do it because I have several other big methods in this model and want to structure the code, don't like lengh of this file. It's getting big > 700 lines of code.
So I want to move my method to another file and import it, so it still can be used like modelmethod
like this:
Order.do_something()
Any ideas?
Use inheritance -- (wiki)
# some_package/some_module.py
class MyFooKlass:
#classmethod
def do_something(cls):
# do something
return 'foo'
# my_app/models.py
from some_package.some_module import MyFooKlass
class Order(models.Model, MyFooKlass):
name = models.CharField()

How can I access the current executing module?

I want to access the calling environment from an imported module.
import child
…
def test(xxx):
print("This is test " + str(xxx))
child.main()
…
now on child:
import inspect
def main():
caller = inspect.currentframe().f_back
caller.f_globals['test']("This is my test")
This works, but it's not fancy. Is there a simplification like 'self' when use in a class? the idea is to do: caller.test('abc') instead.
One option to pass the caller as a parameter like: child.main(self), however self is not available in this context.
Python only load one version of a module so, tempted with this idea:
import sys
myself=sys.modules[__name__]
a then sending myself to the child:
…
child.main(myself)
…
Creates a reference to (a new) module, but not the running one, this is like creating a new class: one code buy a different environment.
If you already have a way of accessing the correct functions and data that works, why not just store f_globals on an instance of a wrapper class and then call things from the instance as if they were unbound properties? You could use the class itself, but using an instance ensures that the data you get from the imported file are valid when you create the object. Then you can access using the dot operator the way you want. This is your child file:
import inspect
class ImportFile:
def __init__(self, members):
self.__dict__.update(members)
def main():
caller = inspect.currentframe().f_back
imported_file = ImportFile(caller.f_globals)
imported_file.test("This is my test")
Outputs:
This is test This is my test
Admittedly, I don't have your setup, importantly the module you're trying to pull from, so it's hard to confirm whether or not this will work for you even though it has for me, but I think you could also use your method of calling main with globals() or even inspect.getmembers() since while inside the module you're importing you're still on the frame you're accessing with f_back from inside child.
The imported module:
import child
def test(xxx):
print("This is test " + str(xxx))
child.main(globals())
Child:
import inspect
class ImportFile:
def __init__(self, members):
self.__dict__.update(members)
def main(caller):
imported_file = ImportFile(caller)
imported_file.test("This is my test")
Outputs:
This is test This is my test

Resources