1

Imagine I have an initializer with optional parameter

def __init__(self, seed = ...):

Now if parameter is not specified I want to provide a default value. But the seed is hard to calculate, so I have a class method that suggests the seed based on some class variables

MyClass.seedFrom(...)

Now how can I call it from that place? If I use self:

def __init__(self, seed = self.__class__.seedFrom(255)):

I definitely don't know what is self at that point. If I use the class name directly (which I hate to do):

def __init__(self, seed = MyClass.seedFrom(255)):

it complains that

name 'MyClass' is not defined

I'm also interested to learn the pythonic way of doing this. And I hope that pythonic way is not hardcoding stuff and making it nil by default and checking it later…

6
  • Yup, it's making it nil by default and checking it later. Commented Jan 25, 2016 at 18:37
  • 1
    That's absolutely the Pythonic way. Default parameter values are only evaluated once, and at method definition time the class name doesn't exist. You could also consider making the classmethod an alternate constructor. Commented Jan 25, 2016 at 18:37
  • "I hope that pythonic way is not ... making it nil by default and checking it later" - Do you want the default seed to be fixed, or do you want to pick a new one each time? If you want a new one each time, you're stuck with that option. Commented Jan 25, 2016 at 18:38
  • 1
    On the other hand, if you want it fixed, define seedFrom first and use a default seed=seedFrom(255), with no self or MyClass. Commented Jan 25, 2016 at 18:39
  • I've reopened the question, since I think it's worth considering the case where it is desirable to call seedFrom only once, when __init__ is defined. Commented Jan 25, 2016 at 18:41

2 Answers 2

2

In case you only need to call seedFrom once, you can do so when __init__ is defined.

class MyClass:

    # Defining seedFrom as a function outside
    # the class is also an option. Defining it
    # as a class method is not, since you still
    # have the problem of not having a class to
    # pass as the first argument when it is time
    # to declare __init__
    @staticmethod
    def seedFrom():
        ...

    def __init__(self, seed=seedFrom()):
        ...
Sign up to request clarification or add additional context in comments.

3 Comments

Good answer. Should note, the staticmethod definition doesn't even take a class parameter (as opposed to classmethod definitions). [per docs.python.org/2/library/functions.html#staticmethod ]
My fault. I started defining it as a class method before I realized that would't work, and forgot to remove cls from the argument list.
Yes, standalone function will work, but what about encapsulation? ;)
0

If you must do this in the init and want the seed method to be on the class, then you can make it a class method, eg as follows:

class SomeClass(object):

    defaultSeed = 255

    @classmethod
    def seedFrom(cls, seed):
        pass # some seed

    def __init__(self, seed=None):
        self.seedFrom(seed if seed is not None else self.defaultSeed)
        # etc

1 Comment

@chepner your edit, whilst not incorrect, is not necessarily the intent either. Any 'falsy' seed would have lead to default seeding, whilst now only not supplying a seed or explicitly using None would have that effect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.