Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
which is "better"?
#1
i wrote a function two different ways. can someone tell me which is better and why?

def pathftn(p,unknown='?'):
    if p.is_symlink:      return 'l'
    if p.is_block_device: return 'b'
    if p.is_char_device:  return 'c'
    if p.is_dir:          return 'd'
    if p.is_file:         return 'f'
    if p.is_socket:       return 's'
    if p.is_fifo:         return 'p'
    return unknown
def pathftn(p,unknown='?'):
    t=unknown
    if   p.is_symlink:      t='l'
    elif p.is_block_device: t='b'
    elif p.is_char_device:  t='c'
    elif p.is_dir:          t='d'
    elif p.is_file:         t='f'
    elif p.is_socket:       t='s'
    elif p.is_fifo:         t='p'
    return t
or do you have a better idea?

edit

in case it mattered to you and you didn't figure it out, p is class Path from pathlib.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
The attributes are callables and not properties.
In your example you are not calling the functions.

This example checks everything.

def pathftn(path):
    mapping = collections.OrderedDict([
        ('is_symlink', 'l'),
        ('is_block_device', 'b'),
        ('is_char_device', 'c'),
        ('is_dir', 'd'),
        ('is_file', 'f'),
        ('is_socket', 's'),
        ('is_fifo', 'p'),
    ])
    return ''.join(
        value if getattr(path, func)() else '_'
        for func, value in mapping.items()
        )
Same function which does the same like yours:

def pathftn(path, unknown='?'):
    mapping = collections.OrderedDict([
        ('is_symlink', 'l'),
        ('is_block_device', 'b'),
        ('is_char_device', 'c'),
        ('is_dir', 'd'),
        ('is_file', 'f'),
        ('is_socket', 's'),
        ('is_fifo', 'p'),
    ])
    for func, value in mapping.items():
        if getattr(path, func)():
            return value
    else:
        return unknown
The mapping can be outside of the function.

So when you see constructs like:

if foo: x=10
elif bar: x=20
elif baz: x=30
else: x=-1
You better use a switch statement like in C.
But Python doesn't have this construct.
Pythonists using as replacement a mapping.
The keys and values of a dict can also be callables (functions or methods).
The benefit is, that you have as first your data structure and afterwards
the code, which is executing the logic. Logic is spitted from data.

To preserve the Order, I use collections.OrderedDict.
In Python 3.7 they guarantee preserving the order in dicts as a
language feature and no longer as implementation detail.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#3
I would rather implement this as a class attribute or a method. Why few several methods to determine what the path is when you can do it with one method?
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#4
The version with all the returns is clear enough here, but in general it is considered bad practice in structured programming to have a method return from any more than one location in the routine.
Reply
#5
I wonder if it would be better to use the stat module's symbolic constants. This would do a os.stat() call for each path, but I don't know how many system calls your code does
import os
import stat

codes = [
    (stat.S_ISLNK, 'l'),
    (stat.S_ISBLK, 'b'),
    (stat.S_ISCHR, 'c'),
    (stat.S_ISDIR, 'd'),
    (stat.S_ISREG, 'f'),
    (stat.S_ISSOCK, 's'),
    (stat.S_ISFIFO, 'p'),
]

def pathftn(path):
    mode = os.stat(str(path), follow_symlinks=False).st_mode
    for func, letter in codes:
        if func(mode):
            return letter
    return '?'
Reply
#6
my bad typing the code into the forum. i left out the () (as dead_eye first noticed). i do make that typo error many times when coding.

(Mar-31-2018, 06:26 PM)Budsy Wrote: The version with all the returns is clear enough here, but in general it is considered bad practice in structured programming to have a method return from any more than one location in the routine.

i've never heard that one (that methods should return from one place) in my many years of C coding (since 1982). i can see how that would have encouraged the use of goto (C does have goto but i only used it it do dropout cleanups after errors).
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#7
The 'one return' statement started with the following letter from Edsger Dijkstra of the Netherlands written in 1968: http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF

For more information about Dijkstra see: https://en.wikipedia.org/wiki/Edsger_W._Dijkstra

The following contains an excellent discussion of the subject: https://softwareengineering.stackexchang...-come-from

Those were the days when FORTRAN 66 was king. The language lacked the IF..THEN..ELSEIF..ELSE construction in modern languages (which was included in FORTRAN 77) which led to either unreadable code, or spaghetti code, or both.

Lewis
To paraphrase: 'Throw out your dead' code. https://www.youtube.com/watch?v=grbSQ6O6kbs Forward to 1:00
Reply
#8
(Apr-02-2018, 09:45 AM)ljmetzger Wrote: Those were the days when FORTRAN 66 was king.
The Dijkstra's letter is against the goto statement, but I don't see anything concerning the single return rule in this letter. As far as I understand this debate, the rule doesn't apply to modern languages. It won't prevent me from writing two or three return statements in a reasonably sized python function. It would be a mistake to address an issue that existed only forty or fifty years ago.
Reply
#9
i saw nothing about a "one return" issue in that letter.

and what about loops? most loops already have one exit path. so there should be "no break" statements under a similar concept. let's ban break statements.

also, infinite loops are just plain bad programming. let's ban those, too.

oh, and recursion ...
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020