Shek
Shek

Reputation: 1613

Getting AttributeError during instantiation of subclass

I am learning inheritance in python, I have a Super class called Cipher and I am expecting a secret_string attribute in init function, I have created a new class Keyword which is inheriting Cipher, in sub class's init I am invoking super class's init, when I am creating an instance of subclass I am passing the required attribute, but it's is giving me an attribute type error.

Main Class :-

 import csv
    import logging

    logging.getLogger().setLevel(logging.INFO)


    class Cipher:
        secret_numbers = []
        orig_dict = {}

        def __init__(self, secret_string, *args, **kwargs):
            # field_names = ["alpha", "posit"]

            self.secret_string = secret_string

            with open("original_assigned.csv", "r") as orig_csv:
                reader = csv.DictReader(orig_csv)
                for row in reader:
                    for k, v in row.items():
                        self.orig_dict[k] = v
                logging.info(self.orig_dict)

            for letter in secret_string:
                self.secret_numbers.append(self.orig_dict.get(letter))

        def get_secret_numbers(self):
            return self.secret_numbers

SubClass :-

class Keyword(Cipher):
    converted_string = []

    def __init__(self, secret_string, *args, **kwargs):
        if len(self.secret_string) < 1:
            raise ValueError("Secret string cannot be empty")
        super().__init__(secret_string)

    @property
    def convert_to_keyword_string(self):
        for num in self.secret_numbers:
            for k, v in self.orig_dict:
                if num == v:
                    self.converted_string.append(k)
        return self.converted_string

Instance creation :-

key = Keyword(["A", "B", "C", "D"])

Error :-

Traceback (most recent call last):
  File "/Users/Documents/workspace/secret_message/cipher.py", line 52, in <module>
    key = Keyword(["A", "B", "C", "D"])
  File "/Users/Documents/workspace/secret_message/cipher.py", line 34, in __init__
    if len(self.secret_string) < 1:
AttributeError: 'Keyword' object has no attribute 'secret_string'

little help please.

Upvotes: 1

Views: 29

Answers (2)

Jean-Fran&#231;ois Fabre
Jean-Fran&#231;ois Fabre

Reputation: 140188

you're calling the parent __init__ method after you're checking for self.secret_string. Just do it first thing in the child __init__ method or self.secret_string isn't defined when you test its length.

def __init__(self, secret_string, *args, **kwargs):
    super().__init__(secret_string)
    if len(self.secret_string) < 1:
        raise ValueError("Secret string cannot be empty")

Note that you can test the length just by doing:

if not self.secret_string:

Upvotes: 1

Anthon
Anthon

Reputation: 76614

You need to call the init of the superclass first, before you can access attributes it sets:

class Keyword(Cipher):
    converted_string = []

    def __init__(self, secret_string, *args, **kwargs):
        super().__init__(secret_string)
        if len(self.secret_string) < 1:
            raise ValueError("Secret string cannot be empty")

or do:

class Keyword(Cipher):
    converted_string = []

    def __init__(self, secret_string, *args, **kwargs):
        if len(secret_string) < 1:
            raise ValueError("Secret string cannot be empty")
        super().__init__(secret_string)

(i.e. remove the self.)

Upvotes: 2

Related Questions