sending a class as an argument

M

manstey

Hi,

Our class has its attributes set as classes, as in

MyClass.Phone.Value='34562346'
MyClass.Phone.Private=True

Inside the MyClass definition we have a function like this:

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

In our code, we then call
We want to be able in our code instead simply to call:
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.

Is there a better way to do this? Thanks
 
S

Steven D'Aprano

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

We want to be able in our code instead simply to call:

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().
 
G

Gabriel Genellina

Our class has its attributes set as classes, as in

MyClass.Phone.Value='34562346'
MyClass.Phone.Private=True

Inside the MyClass definition we have a function like this:

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

This method does not use `self` at all, and that's rather suspicious for
an instance method.
And you set properties on the class itself? So you never create instances
of that class?
In our code, we then call

We want to be able in our code instead simply to call:

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.

Surely an AttributeError, because you dont have any attribute named "attr".
Notice that on this version you are using `self`, but on the above version
you didnt use it.
There are easy ways in Python to access an attribute by name, but I think
that this would just add more noise to your code. Please tell us about
your design, or rethink it. Do actually exist instances of MyClass, or
not? I can imagine "Phone" being an attribute of a certain instance of
Person, by example, but not a class attribute.
Is there a better way to do this? Thanks
Surely, but we need to know your goal, what do you really want to do, not
how do you think you should do that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,681
Members
48,796
Latest member
Greg L.

Latest Threads

Top