質問

I'm attempting to create a dictionary of executable functions within a class. But having trouble getting the self parameter to work correctly.

Consider the following code:

class myclass(object):

  def x(self):
   return 'x'

  def y(self):
   return 'y'

  EF= {
   'a':x,
   'b':y,
  }

  def test(self):
    print self.EF['a']()

When I attempt to execute the 'test' function of the class, I get an error around the number of parameters as it evaluates and executes one of the functions in the dictionary.

>>> class myclass(object):
...   def x(self):
...    return 'x'
...   def y(self):
...    return 'y'
...   EF= {
...    'a':x,
...    'b':y,
...   }
...   def test(self):
...     print self.EF['a']()
...
>>>
>>>
>>> m=myclass()
>>> m.test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 11, in test
TypeError: x() takes exactly 1 argument (0 given)

I've tried a few variations, including this which doesn't work.

  EF= {
   'a':self.x,
   'b':self.y,
  }

The only thing that did work was when I explicitly passed self as a parameter, like this.

...   def test(self):
...     print self.EF['a'](self)
...
>>> m=myclass()
>>> m.test()
x

I've seen other questions about using a dictionary to index functions, but none from within a class.

Here are my questions:

  • What is the proper way to do handle the self parameter?
  • I'd prefer to move my dictionary constant outside of the class into my constants section. Can I do that, and if so how? Should I do that?
  • If I should/have to have my dictionary within my class, why can't I move it to the top of the class?

That's all I got. Thanks for the help.

役に立ちましたか?

解決

What is the proper way to do handle the self parameter?

Python uses the self identifier in similar ways to other imperative languages using the this identifier, but it is explicit (as explicit is better than implicit!)

This allows you to use the class as either an instantiated object, or the static class itself.

For an instantiated version, you are probably looking for

>>> class myclass:
    def __init__(self):
        self.EF = {'a':self.x,'b':self.y}
    def x(self):
        return 'x'
    def y(self):
        return 'y'
    def test(self):
        print self.EF['a']()


>>> my_test_class = myclass()
>>> my_test_class.test()
x

I'd prefer to move my dictionary constant outside of the class into my constants section. Can I do that, and if so how? Should I do that?

If you wanted to use them as static method in a dict outside your class definition, you would need to use the @staticmethod decorator

>>> class myclass(object):
    @staticmethod
    def x():
        return 'x'
    @staticmethod
    def y():
        return 'y'


>>> EF = {'a':myclass.x,'b':myclass.y}
>>> EF['a']()
'x'

If I should/have to have my dictionary within my class, why can't I move it to the top of the class?

Any object attributes should be defined either in the __init__ function, or by explicitly setting them.

他のヒント

Having the dictionary in an init method will make it work

class Myclass(object):
        def x(self):
                return 'x'

        def y(self):
                return 'y'

        def __init__(self):
                self.EF= {
                        'a':self.x,
                        'b':self.y
                }

        def test(self):
                print self.EF['a']()

m=Myclass()
m.test()

In reference to your questions. The class is kind of a dictionary or named tuple of attributes and executable functions. The functions themselves only define behavior. self is a sack of state related to your instance. if you save a pointer to that function somewhere else and provide it with a given self that is an instance of your class it should work as normal.

class MyClass(object):
    def __init__(self, x):
        self.x = x
    def fun(self):
        return self.x

i = MyClass(1)
print i.fun()

f = MyClass.fun
i2 = MyClass(2)

print f(i2)

When you call using the standard i.fun() all it's doing is passing i in implicitly as the selfargument.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top