2

I have a class called Grammar, which holds a collection of production rules. Before doing things with a Grammar object, I usually need to add a few extra rules to it, which should be forgotten after the current task is done. So, I'd like to add a method that returns a new Grammar object, containing all the current object's rules as well as the new ones.

I could call this method .add, like this:

class Grammar:

    def add(self, *rules):
        '''Returns new Grammar object, with 'rules' added.'''
        . . .

but .add conventionally seems to mean a method that modifies a collection by adding new elements to it.

Is there a naming convention in Python for a method that returns a new collection, with new elements "added", without giving the reader the expectation that it modifies the object?


Operator overloading?

I know that the .__add__ method is invoked by the + operator, and there the convention is indeed that the object is not modified—like this:

working_grammar = grammar + [rule1, rule2, rule3]

I am thinking to avoid overloading an operator, in favor of a meaningful method name. However, if the overloaded operator produces conventional, expected, readable code, I'd like to know more about that—perhaps a well-known precedent in a library, or advice in a well-known style guide.

Ben Kovitz
  • 4,920
  • 1
  • 22
  • 50

2 Answers2

1

I usually name functions with the output. Also, use verb+object. Some suggestions:

  • add_rule (or addRule())
  • added
  • added_rule
  • insert

For 'returns a new collection, with new elements "added"'. What is the usual collection? List, tuple, set?

  • add_to_rule_list
  • add_to_rule_set

You may also follow the PEP 8 -- Style Guide for Python Code

Omr
  • 39
  • 4
1

concat comes not only from Python but also C and C++; it means "add the item and then return a reference to the collection", like string concatenation, or array concatenation.

class Grammar:

    def concat(self, rules):
        '''Returns new Grammar object, with 'rules' added.'''


working_grammer = grammar.concat([rule1, rule2, rule3])

pandas.concat

You could even extend your concat method for arrays of rules and other Grammar objects

class Grammar:
    def concat(self, *grammarlike):

grammarC = grammarA.concat(grammarB, [ruleD, ruleE])
richytong
  • 2,387
  • 1
  • 10
  • 21