patternpythonMinor
Out of order class resequencer
Viewed 0 times
orderoutresequencerclass
Problem
I got bored recently and wrote a tool to re-order out of order classes in Python files. This can occur with some auto-generation code tools for databases and the like; these files can sometimes be thousands of classes big.
I've posted it here to gauge its general utility and get feedback on the code (logic flow, readability, etc).
mr_agreeable is the tool and classes_test is the out of order test script.
mr_agreeable.py:
```
import os
import sys
from codecs import encode
from random import randint
import getopt
import inspect
import types
__doc__ = \
'''
A python script that re-orders out of sequence class defintions
'''
class rebase_meta(type):
'''
Rebase metaclass
Automatically rebases classes created with this metaclass upon
modification of classes base classes
'''
org_base_classes = {}
org_base_classes_subs = {}
base_classes = {}
base_classes_subs = {}
mod_loaded = False
mod_name = ""
mod_name_space = {}
def __init__(cls, cls_name, cls_bases, cls_dct):
#print "Making class: %s" % cls_name
super(rebase_meta, cls).__init__(cls_name, cls_bases, cls_dct)
# Remove the old base sub class listings
bases = rebase_meta.base_classes_subs.items()
for (base_cls_name, sub_dict) in bases:
sub_dict.pop(cls_name, None)
# Add class to bases' sub class listings
for cls_base in cls_bases:
if(not rebase_meta.base_classes_subs.has_key(cls_base.__name__)):
rebase_meta.base_classes_subs[cls_base.__name__] = {}
rebase_meta.base_classes[cls_base.__name__] = cls_base
rebase_meta.base_classes_subs[cls_base.__name__][cls_name] = cls
# Rebase the sub classes to the new base
if(rebase_meta.base_classes.has_key(cls_name)): # Is class a base class
subs = rebase_meta.base_classes_subs[cls_name]
rebase_meta.base_classes[cls_name] = cls # Update base class dictionary to new clas
I've posted it here to gauge its general utility and get feedback on the code (logic flow, readability, etc).
mr_agreeable is the tool and classes_test is the out of order test script.
mr_agreeable.py:
```
import os
import sys
from codecs import encode
from random import randint
import getopt
import inspect
import types
__doc__ = \
'''
A python script that re-orders out of sequence class defintions
'''
class rebase_meta(type):
'''
Rebase metaclass
Automatically rebases classes created with this metaclass upon
modification of classes base classes
'''
org_base_classes = {}
org_base_classes_subs = {}
base_classes = {}
base_classes_subs = {}
mod_loaded = False
mod_name = ""
mod_name_space = {}
def __init__(cls, cls_name, cls_bases, cls_dct):
#print "Making class: %s" % cls_name
super(rebase_meta, cls).__init__(cls_name, cls_bases, cls_dct)
# Remove the old base sub class listings
bases = rebase_meta.base_classes_subs.items()
for (base_cls_name, sub_dict) in bases:
sub_dict.pop(cls_name, None)
# Add class to bases' sub class listings
for cls_base in cls_bases:
if(not rebase_meta.base_classes_subs.has_key(cls_base.__name__)):
rebase_meta.base_classes_subs[cls_base.__name__] = {}
rebase_meta.base_classes[cls_base.__name__] = cls_base
rebase_meta.base_classes_subs[cls_base.__name__][cls_name] = cls
# Rebase the sub classes to the new base
if(rebase_meta.base_classes.has_key(cls_name)): # Is class a base class
subs = rebase_meta.base_classes_subs[cls_name]
rebase_meta.base_classes[cls_name] = cls # Update base class dictionary to new clas
Solution
Some tidbits:
Might be anal, but I would have sorted my imports differently. For me it just makes it easier to find what I am looking for, but I can see why you might separate the way you did:
Classes should be camelcase (pep8 compliance)
For lines:
I might write as (remove extraneous parens):
These lines are already readable, not sure if the extra parens is buying anything other than preference. I prefer to save the 1 or 2 keystrokes. =)
For line:
Consider making this multiline to be pep8 compliant. (79 chars max)
Ditto here:
Line:
CamelCase preferred per pep8. MisterQuiet
More ditch the parens:
Consider creating a def main(), and changing your if name statment to:
Hopefully some of these idioms are helpful.
Might be anal, but I would have sorted my imports differently. For me it just makes it easier to find what I am looking for, but I can see why you might separate the way you did:
import getopt
import inspect
import os
import sys
import types
from codecs import encode
from random import randintClasses should be camelcase (pep8 compliance)
RebaseMetaFor lines:
if(not rebase_meta.base_classes_subs.has_key(cls_base.__name__)):
if(not self.mod_loaded):
if(cls_name == sub_cls_name):I might write as (remove extraneous parens):
if not rebase_meta.base_classes_subs.has_key(cls_base.__name__):
if not self.mod_loaded:
if cls_name == sub_cls_name:These lines are already readable, not sure if the extra parens is buying anything other than preference. I prefer to save the 1 or 2 keystrokes. =)
For line:
org_class_types = filter(lambda x: isinstance(x, type) and (not x.__name__ inConsider making this multiline to be pep8 compliant. (79 chars max)
Ditto here:
class_types = [(cls.__name__, rebase_meta(cls.__name__, (cls,), {})) for cls in org_class_types]Line:
class mr_quietCamelCase preferred per pep8. MisterQuiet
More ditch the parens:
for (key, value) in optlist:Consider creating a def main(), and changing your if name statment to:
if__name__ == __main__:
sys.exit(main())Hopefully some of these idioms are helpful.
Code Snippets
import getopt
import inspect
import os
import sys
import types
from codecs import encode
from random import randintif(not rebase_meta.base_classes_subs.has_key(cls_base.__name__)):
if(not self.mod_loaded):
if(cls_name == sub_cls_name):if not rebase_meta.base_classes_subs.has_key(cls_base.__name__):
if not self.mod_loaded:
if cls_name == sub_cls_name:org_class_types = filter(lambda x: isinstance(x, type) and (not x.__name__ inclass_types = [(cls.__name__, rebase_meta(cls.__name__, (cls,), {})) for cls in org_class_types]Context
StackExchange Code Review Q#28254, answer score: 2
Revisions (0)
No revisions yet.