1

I need some help with generating an instance of an object.

Lets say I have an object being created from NewPerson but I do not put a name within the parameter like so:

dave = NewPerson()

I want to generate a random name using my generate_name function. Here is my current code, but I'm getting the error: NameError: name 'generate_name' is not defined

class NewPerson(object):
    def __init__(self, name = generate_name()):
        self.name = name
        self.age = 0

    def set_name(self,name):
        self.name = name

    def get_name(self):
        return (self.name)

    def generate_name(self):
        self.name = Generator.get_full_name()
wwii
  • 23,232
  • 7
  • 37
  • 77
ScottRedrup
  • 91
  • 1
  • 7
  • 2
    Forget about accessors in Python, just use `myclass.instance_variable`. If you need to, you can add accessors later if you truly need them by a change to the class definition, not all places that reference it. See http://stackoverflow.com/questions/13852279/what-is-the-benefit-to-using-a-get-function-for-a-python-class for more detail. – msw Dec 13 '14 at 00:30

3 Answers3

2

the import random and generate_name function are because i dont know what your Generate class does

import random #just for a quick generate random name thing
class NewPerson(object):
    def __init__(self, name = fart_knock()):
        #this entire if/else block is equivilant to "self.name = name or self.generate_name()", thanks troolee
        if name == None:
            self.name = self.generate_name()
        else:
            self.name = name
        self.age = 0

    def generate_name(self):
        #because i have no idea how your Generator class works
        return str(random.randrange(9999))

yours isnt working properly, because you are trying to assign a function inside of the class into the init method. it doesnt know what it is before you create it. ( even if it did, it would do it once and every single random name would be the exact same)

also when calling a method inside of a class, inside of the class you need to refer to it as self.generate_name() instead of just generate_name()

TehTris
  • 3,139
  • 1
  • 21
  • 33
  • 1
    `self.name = name or Generator.get_full_name()` – Pavel Reznikov Dec 13 '14 at 00:38
  • heh. thats pretty cool, i never thought of that. just looking at it (and before your edit) i thought you were crazy.... still not sure how it works, because on the surface it looks like `name or Generator.get_full_name()` should return a boolean ( i guess because i mostly use `or` in statements like `if a or b:`, (assuming `Generator.get_full_name()` returns a string of course – TehTris Dec 13 '14 at 00:47
  • 1
    Operator `or` will return first non-false value. Also `or` is lazy, it means python will never call `Generator.get_full_name()` if name will be non-calse (None, empty string, 0, False, {}, (), [], etc). – Pavel Reznikov Dec 13 '14 at 00:58
1

Firstly, to call functions on the instance, you need to preface them with self:

self.generate_name()

Secondly, if you put the generate_name call in the function header, it will be called when the function is defined and not again -- so you'll have one "random" default name.

Thirdly, if you really want that behavior, you have to define generate_name first, and leave self off (both when you call it and when you define it):

class NewPerson(object):

    def generate_name():
        blahblah

    def __init__(self, name=generate_name()):
        blahblah

This makes generate_name useless once the class is finished being constructed, unless you add something like:

    generate_name = staticmethod(generate_name)

towards the bottom of the class.

Ethan Furman
  • 63,992
  • 20
  • 159
  • 237
1

There are a couple of issues here:

(1) You need to indent after you declare the class - in this case all of your member function definitions

(2) Because of the indent problem, it's not clear if you want 'generate_name' to be a member function of the NewPerson class or if you want it to be a stand-alone function. If you don't want it to be inside the class, then simply move its definition to before the definition of NewPerson, and everything should work fine:

def generate_name():
   [code here]

class NewPerson(object):
   [code here]

On the other hand, if you DO want generate_name to be a member function of NewPerson, then you can't do what you're trying, but a simple fix is something like the following (pay attention to the indenting):

def NewPerson(object):
   def __init__(self, name = None):
      if name == None:
         self.name = self.generate_name()
      else:
         self.name = name
   def generate_name(self):
      [code here]

The take-away message is that you need to use indenting to tell Python which pieces of code go with which other pieces. These are called code block and in other languages they might be handled with operators like { }, but in Python, having your indentation correct is very important since this marks your code blocks!

cipher42
  • 81
  • 6