简体   繁体   中英

How to use a function outside a class as a property inside a class?

I'm having some problems. How we can define a function outside of a function that can be used in a class property? Also, how we can insert the self parameter into the function signature? I would like to visualize it like this:

>>> def a(self, x):   #I thought maybe class will give "self" to this property function
...     print(self)
... 
>>> class aa:
...     def __init__(self):
...         pass
...     @a
...     def p():
...         print('in it')
... 
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 4, in aa
    TypeError: a() missing 1 required positional argument: 'x'

I want to define a function outside but to use inside of a class. Like a class's method as a property. How can I do this?

It's not really clear what you want your out-of-class function to do. There are a bunch of possibilities, but you may not know the terminology yet to describe it to us.

Here's the three I think are most likely:

  1. You may want your function to be a decorator . That means you can apply it to a method with @decorator syntax to other functions, including methods in a class.

    For this to work, your function needs to be written to accept a function object as its only argument. Whatever it returns is what will replace the function or method it was being called on, so usually you want to return a callable, but you could instead return a descriptor like property does. Try something like this:

     def decorator(func): def wrapper(self, *args, **kwargs): print("in the wrapper") result = func(self, *args, **kwargs) print("wrapper is done") return result return wrapper class Foo: @decorator def foo(self, x): print("in foo(), x is", x) f = Foo() f.foo(1) # prints three messages

    When you call the foo method, you're actually going to be calling the wrapper method that the decorator returned after it was applied to the original method ( func ). Because of how we wrote the wrapper, it will call func so the original method prints out its message too.

  2. You may want to use property (a descriptor type) to call your out-of-class function. This is a less common way of using property than applying it as a decorator on a method, but it's not impossible. You could even have two different functions, one to be called when requesting the attribute, the other than will be called when setting it (but I'll demonstrate with just the getter):

     def getter(obj): print("in the getter") return 1 class Foo2: foo = property(getter) f2 = Foo2() print(f2.foo) # prints a message from the getter function first, then prints 1

    Note that you can't use @decorator syntax when building a property this way. That is only legal syntax immediately before a function definition, and we're not defining any functions that way inside our class.

  3. You may just want to copy a function defined outside of the class into it, without any decorator or property nonsense. This is the easiest one to do, it's just a simple assignment:

     def func(self, x): print("x is", x) class Foo3: method = func # just assign the global to a name in the class body func = func # you can even use the same name if you don't mind confusing people f3 = Foo3() f3.method(1) f3.func(2)

If you want to create a property that uses a function defined outside your class, it would be something like this:

def myfunc(self):
    return self._p

class Foo:
    def __init__(self, p):
        self._p = p
    p = property(myfunc)

f = Foo("Alpha")
f.p # gives "Alpha"

property accepts a function as its (first) argument. The function should have self as a parameter, and should return the value that you want the property to evaluate to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM