Search code examples
pythonpython-3.xbiopythonclass-methodpep8

Python question about overridden/redefined imported function as Class method


In https://github.com/biopython/biopython/blob/518c4be6ae16f1e00bfd55781171da91282b340a/Bio/SeqUtils/ProtParam.py I have this importing statement:

from Bio.SeqUtils import molecular_weight

and then in a class:

class ProteinAnalysis:

.....
.....
    def molecular_weight(self):
        """Calculate MW from Protein sequence."""
        return molecular_weight(
            self.sequence, seq_type="protein", monoisotopic=self.monoisotopic
        )

......
......

What is this type of coding called? Is it normal to call imported function and class method with same name?

To my knowledge, self.molecular_weights is not equal to molecular_weights, but why call them the same? Is that PEP 8 compliant?

Would

a = ProteinAnalysis()

print(a.molecular_weights == molecular_weights)

give True or False?

What about:

print(a.molecular_weights(*args,**kwargs) == molecular_weights(*args, **kwargs))


Solution

  • Yes. This is normal as there is no contradiction. You cannot freely get access to any class attributes even in methods inside a class. For example, let's look at this:

    var = 5
    
    class SomeClass:
        var = 6
    
        def show(self):
            print(var)
    
    SomeClass().show()
    

    The result is 5. As there is only one "variable" var in global scope.

    If we unlink it via del var, we will get NameError:

    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    Input In [38], in <cell line: 1>()
    ----> 1 SomeClass.show()
    
    Input In [37], in SomeClass.show()
          5 def show():
    ----> 6     print(var)
    
    NameError: name 'var' is not defined
    

    But you can get free access during the class initialisation:

    class SomeClass:
        var = 6
        print(var)
    
        def show():
            print(var)
    

    Hereinabove code prints 6.

    In Biopython code only the imported function is used because the calling is inside a method where there is no direct access to the class attributes. Moreover, the method even is not initialised at the moment.

    a.molecular_weights == molecular_weights gives False because even if they do the same they are different objects: a method & a function.

    molecular_weights() == a.molecular_weights() would give True, if the same arguments are sent.

    There is no contradiction with PEP8 naming rules as both do the same but one is a function, other is a method of appropriate class and objects.