How can I balance “Pythonic” and “comfortable” in this case?

I have an “interface” that will be implemented by client code:

class Runner:
    def run(self):
        pass

runshould generally return a docutils node, but because far the usual case is ordinary text, the caller allows you to runreturn a string that will be checked with type()and turns into node.

However, as I understand “Pythonic”, it is not “Pythonic”, because checking type()something does not allow it to “be” a type of “acting”, as one - i.e. the code "Pythonic" should use duck print.

I considered

def run_str(self):
    pass

def run_node(self):
    return make_node(self.run_str())

but I don’t care about it, because it puts a not very interesting type of return right there in the title; it is distracting.

- , ? , , "" ( )?

+5
5

, ; - . , , " ", , , run.

run, , ! ( , run, a Runner.) type isinstance run .

, node, - . node, , ! , a node, . , , , , , .

" ", . , , .

, , Pythonic , run node. isinstance type . , node, , , , , docstring, , run node.

, , , , , . , , isinstance(obj, basestring) ( type(obj) == str, Unicode ..). , ; , , , , .

( , , iter , , .)

+5

, - , . - :

def run(self):
    try:
        ...assume it a str   
    except TypeError:
        ...oops, not a str, we'll address that

, (EAFP), .

+2

. - :

def run(self,arg):
    try:
        return make_node(arg)
    except AlreadyNodeError:
        pass

make_node AlreadyNodeError, node.

+1

type() , (str ), - isinstance():

if isinstance(my_var, str):
    my_code_here()

Also, the pythonic way of doing this would be duck, as you mentioned, why don't you just put the code in the try/ block except? Thus, an exception will be caught only if the value does not act as expected (if it wanders and goes like a duck, it's a duck).

+1
source
class Node(object):
  def __new__(cls, contents):
    return contents if isinstance(contents, cls) else object.__new__(cls)
  def __init__(self, contents):
    # construct from string...

class Manager(object):
  def do_something(self, runner, *args):
    do_something_else(Node(runner(*args)))

Now it doesn't matter if the runner returns a Node or a string.

0
source

All Articles