Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Good practice of Python : Cutting variable names as parameters

Pretty sure I know the answer to this question, but wanted to ask the python community about that.

I'm working on a python project where the current trend is to cut the variable name or the class name to pass it as parameters in other methods... Like :

myVar.__classname__[6:] 

or worst :

try :
    ...
except Error as err :
    myVar = err.message.split(':')[0]
    getattr(myInst, myVar)

etc... that said, we have to respect a really strict naming convention that will fit with all those horrible line of codes, but I was wondering if that was a common practice and that I was completely out of the line or if I was correct to say that this is just... awful.

It seems like a very bad idea to me, but as we have no choice...

Thanks for any response that would help me

Edit : This is the actual code in the try/except if you would like to have more details :

except ValueError as err:
    field_error = self.klass.__name__ + '_' + err.message.split(':')[0]
    getattr(self.ui, field_error).setText(err.message) 

Edit : So as some asked for more details :

In the example above, We wanna set an error message in a field when value entered by user is wrong.

self.klass represent an SQL Alchemy class, and the "Naming convention" says that every field should start with the SQL Alchemy class name in front of it, then an underscore, and then the field where we set the error message ( currently the same that the user entered wrong ).

This will "construct" ( Oh god... this feels so bad ) the name of the ui field that is wrong, then we'll get it with the getattr on the general ui.

This feels very wrong as it is based on a naming convention that might have billions of exceptions when we'll start to have more classes... Actually, I wouldn't mind fixing this, but the entire project is based on this naming convention. The first example is based on the fact that we have different ui files for our app, and these are indexed by a code ( like 7CDGR01 ). These are then completed by a class to add behaviour ( signal processing... etc ). If I keep the same example, the class is named : Screen7CDGR01. Therefore, to have the code of the screen, you get the end of the classname, from the 6th caracter... then send it to another method etc, etc...

Think you all got it, this is not what I voted for, I think this is just bad, I'm no expert in python, but I think that even if python allows us to do a lot, it should not be used like that.

like image 984
Syrupsystem Avatar asked Jun 26 '13 08:06

Syrupsystem


2 Answers

It's dangerous to use introspection on variables/class names because, in Python, names aren't consistent : Python introspection: access function name and docstring inside function definition

#!/usr/local/bin/python2.7


class myInst(): 
  iitt = 15
  pass

class deco():
    def __init__(self, id, *args, **kws):
        self.__id = id
        self.iitt = 25
        self.__name__ = "another name"

@deco
class myInst2():
  iitt = 15
  pass


# Overriding class name
print "MyInst name :", myInst.__name__    #"myInst"
print "MyInst2 name :", myInst2.__name__  #"another name"


# Overriding attribute value
try:
  raise ValueError("iitt: Error!")
except ValueError as err:
  myVar = err.message.split(':')[0]
  l = getattr(myInst, myVar)
  print l                                 # 15

try:
  raise ValueError("iitt: Error!")
except ValueError as err :
  myVar = err.message.split(':')[0]
  l = getattr(myInst2, myVar)
  print l                                 # 25

#Duck Typing
myInst = myInst2
try:
  raise ValueError("iitt: Error!")
except ValueError as err :
  myVar = err.message.split(':')[0]
  l = getattr(myInst, myVar)
  print l                                 # 25
like image 144
lucasg Avatar answered Oct 29 '22 16:10

lucasg


In addition to what was said about Decorators, it's important to know that this kind of code is very difficult to read.

Python is known for its readability, things like

err.message.split(':')[0]

are very hard to understand by anyone new in the project. A mere suggestion on what could be done:

Except ValueError as valueError:
    validationError = new ValidationError(valueError)
    componentSelector = validationError.getComponentSelector(self.getClassName())
    getattr(self.ui, componentSelector).setText(validationError.message)

That way all unreadable code is encapsulated inside of getComponentSelector() method. And this is only one of possible solutions.

If you want to know what's good and bad when programming in Python, take some time to read https://stackoverflow.com/questions/228181/zen-of-python .

like image 25
Mironor Avatar answered Oct 29 '22 17:10

Mironor