Instantiating a class with metaclass, using class function to assign an attribute

Viewed 43

I want to define attribute at class instantiation using a function from inside the class definition.

The derivation depends on one varying variable (self.name) or the very name of the object, which is passed on during instantiation.

class Dog:
    def __init__(self,

    name,
    date,
    oranges_in_stomach
    
    ):

        self.name = name
        self.date = date
        self.oranges_in_stomach = oranges_in_stomach

    def inspect_stomach(self):
        x=self.name
        return x

    def count_oranges_in_stomach(self):
        n_oranges = inspect_stomach(self)
        return n_oranges


Husky = Dog(
    'Husky'
    '00:00:0000',
    oranges_in_stomach = self.oranges_in_stomach(self)
    )

Obviously:

NameError: name 'self' is not defined

How to make python first execute the function count_oranges_in_stomach(), taking the self.name from **Husky** = Dog('husky'...) or Husky.name and then assign the result to Husky.oranges_in_stomach?

I've tried experimenting with globals() but to no avail so far. Completely new to the topic of metaclasses - and If I understand correctly, I'd have to create a metaclass like this:

class Meta(type):
    def __new__(cls, name, bases, dct):
        x = super().__new__(cls, name, bases, dct)
        x.name = name
        return x

How to specify that x.name would equal what I will type here: Husky = Is it already done in my example above? It throws a TypeError: type.__new__(X): X is not a type object (str). [Why is "X" a capital letter in the error?]

If I managed to put that orange-counting function in the metaclass, how to call this function using the name? [How can I access the bases,dct to experiment more?]

In other words - I want the metaclass to call this:

Husky.count_oranges_in_stomach()

during the Husky instantiation, as soon as it reads Husky and before it's done, pass that as Husky.oranges_in_stomach so it doesn't cause error. In the second method, call this as soon as it reads my self.name definition.

If I understand correctly, metaclasses are matrixes for instantiation. How to use them to accomplish those goals?

Hints appreciated:)

1 Answers

What you intend to do is confusing beyond understanding and there is no way to answer this. Obviously the code can't do magic: in your example code the method you want to run prior to instantiation (which is a possible thing with classmethods) depends on another method which reads an attribute, which is set inside the __init__ code. It is clear that if that code is not run, there is no self.name and your inspect_stomach will fail.

There is no way to guess how to "fix" this, since it makes no sense to start with.

State what you need, with some example code that makes sense (out of returning a dog's name as "number of oranges"), and maybe someone will be able to help you.

It feels like all you need are classmethods and some properties, but there is no way to tell for sure.

Related