sending a class as an argument

Steven D'Aprano steve at REMOVEME.cybersource.com.au
Mon Jan 29 00:46:54 EST 2007


On Sun, 28 Jan 2007 20:24:23 -0800, manstey wrote:

> Hi,
> 
> Our class has its attributes set as classes, as in
> 
> MyClass.Phone.Value='34562346'
> MyClass.Phone.Private=True

The Python convention is that classes have initial capitals (MyClass),
instances do not, and nor do attribute names.

I'm thinking you're doing this:

class Phone: pass
class MyClass: pass

# now set a _class_ attribute -- all instances share this attribute
MyClass.Phone = Phone()  # attribute name is the same as a class

Why do all instances of MyClass share the same phone number?

I think that's a bad design. You should probably do this:

# now set an _instance_ attribute
instance = MyClass()
instance.phone = Phone()

Of course, in practice you'd do this in an __init__ method rather than as
two separate lines:

instance = MyClass()  # automatically creates instance.phone


Of course, I could be wrong -- you haven't really given enough information
for me to be sure what you're doing.


> Inside the MyClass definition we have a function like this:

The word is "method", not function. Methods live in classes, functions
outside.

 
> def MyFunc(self,clsProperty):
>    if clsProperty.Private:
>         print 'Private property'
>    else:
>         print ClsProperty.Value

If you have a whole lot of attributes with the same attribute (in this
case, private), you should really be thinking about a more object-oriented
design. As it stands now, your MyClass needs to know all the fundamental
workings of your Phone class, your Name class, your Address class, etc.
That's bad design. Your MyClass should just say "give me your value" and
the Phone class should know that if it is private, it returns "private
property". Etc.



> In our code, we then call
>>>> MyClass.MyFunc(MyClass.Phone)
>
> We want to be able in our code instead simply to call:
>>>> MyClass.MyFunc(Phone) or MyClass.MyFunc('Phone')
> 
> But we can't get it to work. If we rewrite the function as follows:
> 
> def MyFunc(self,attr):
>    if self.attr.Private:
>       print 'Private'
>    else:
>       print self.attr.Value
> 
> we get an error.

Oooh, no don't tell us what it is, let me guess! I love guessing games!

Does it crash your PC?

Here's how I would do it. Each attribute should know how to "MyFunc"
itself: give it a myfunc method.

class Phone:
    def __init__(self, number, private=False):
        self.phonenumber = number
        self.private = private
    def myfunc(self):
        if self.private:
            return "private"
        else:
            return str(self.phonenumber)


Now you can simplify your MyFunc method:

def myfunc(self, attrname):
    """Delegate myfunc to the named attribute."""
    return getattr(self, attrname).myfunc()

Or not even bother, and just write MyClass.phone.myfunc(). 



-- 
Steven D'Aprano 





More information about the Python-list mailing list