This question already has answers here:
How can I call a function within a class?
(2 answers)
Closed 6 months ago.
How can i call a private function from some other function within the same class?
class Foo:
def __bar(arg):
#do something
def baz(self, arg):
#want to call __bar
Right now, when i do this:
__bar(val)
from baz(), i get this:
NameError: global name '_Foo__createCodeBehind' is not defined
Can someone tell me what the reason of the error is?
Also, how can i call a private function from another private function?
There is no implicit this-> in Python like you have in C/C++ etc. You have to call it on self.
class Foo:
def __bar(self, arg):
#do something
def baz(self, arg):
self.__bar(arg)
These methods are not really private though. When you start a method name with two underscores Python does some name mangling to make it "private" and that's all it does, it does not enforce anything like other languages do. If you define __bar on Foo, it is still accesible from outside of the object through Foo._Foo__bar. E.g., one can do this:
f = Foo()
f._Foo__bar('a')
This explains the "odd" identifier in the error message you got as well.
You can find it here in the docs.
__bar is "private" (in the sense that its name has been mangled), but it's still a method of Foo, so you have to reference it via self and pass self to it. Just calling it with a bare __bar() won't work; you have to call it like so: self.__bar(). So...
>>> class Foo(object):
... def __bar(self, arg):
... print '__bar called with arg ' + arg
... def baz(self, arg):
... self.__bar(arg)
...
>>> f = Foo()
>>> f.baz('a')
__bar called with arg a
You can access self.__bar anywhere within your Foo definition, but once you're outside the definition, you have to use foo_object._Foo__bar(). This helps avoid namespace collisions in the context of class inheritance.
If that's not why you're using this feature, you might reconsider using it. The convention for creating "private" variables and methods in Python is to prepend an underscore to the name. This has no syntactic significance, but it conveys to users of your code that the variable or method is part of implementation details that may change.
Related
I am a beginner in Python and have gone through some help material on __ symbol and my question is based on it.
I have executed the following in a Python 3.7 shell / interpreter:
class __:
... def strangeClassName():
... print("Inside a function")
…
inst = __()
which is not problematic at all. However, when I try to access the print statement using the function name(strangeClassName()), I am not able to get it. I mean - not able to see the print's output.
What is happening and how to access the function, as the call inst.strangeClassName did not help!
You must specify the first argument that represents the instance object for all instance methods. The name self is only convention and you can name it your way. But following the convention is the good practice.
Looks like this:
class __:
def foo(self):
print("inside")
inst = __()
inst.foo()
Output:
inside
So I have a class, which I'm using as a local namespace. I have some static functions in the class, but they can't access the class scope variables. Why is this?
class Foo:
foo_string = "I am a foo"
#staticmethod
def foo():
print foo_string
>>> Foo.foo()
[Stack Trace]
NameError: global name 'foo_string' is not defined
Any thoughts?
Python doesn't let class variables fall into scope this way, there are two ways to do this, the first is to use a class method:
#classmethod
def foo(cls):
print(cls.foo_string)
Which I would argue is the best solution.
The second is to access by name:
#staticmethod
def foo():
print(Foo.foo_string)
Do note that in general, using a class as a namespace isn't the best way to do it, simply use a module with top-level functions instead, as this acts more as you want to.
The reason for the lack of scoping like this is mainly due to Python's dynamic nature, how would it work when you insert a function into the class? It would have to have special behaviour added to it conditionally, which would be extremely awkward to implement and potentially fragile. It also helps keep things explicit rather than implicit - it's clear what is a class variable as opposed to a local variable.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Python 'self' keyword
In Python, instance methods must have the instance passed to them as an argument, like:
class Foo:
def bar(self):
print self.name
What's the purpose of making this explicit? (Is it simply implicit < explicit?) In what circumstances would you would want to do pass something other than "self"?
A Python instance method is just a function that is bound to the instance. When called the instance always passes itself as the first argument.
The name self is just a convention. You can call it anything you want. So you could do this:
class Foo:
def bar(s):
print s.name
But don't, because it breaks convention. :)
I have a class with many methods. How can I modify my methods so that they can also be accessed directly as a function without creating object of that class? Is it possible.
The methods will be "unbound" (meaning, essentially, that they have no self to work with). If the functions do not operate upon self, you can turn them into static-methods (which do not take a self first argument) and then assign them to variables to be used like functions.
Like so:
class MyClass(object):
#staticmethod
def myfunc():
return "It works!"
myfunc = MyClass.myfunc
myfunc() # prints "It works!"
Essentially, you need to ask yourself "What data does my method need to (er) function?" Depending on your answer, you can use #staticmethod or #classmethod or you may find that you do in fact need a self in which case you will need to create an object before trying to use its methods.
That final case would look something like:
myobj = MyClass()
del MyClass # This is a singleton class
myfunc = myobj.myfunc
All of that aside, if you find that all of your methods are actually staticmethods, then it's better style to refactor them out of the class into plain-old functions, which they really are already. You may have learned this "class as namespace" style from Java, but that isn't correct in Python. Python namespaces are represented by modules.
Unbound Methods
To create an unbound method (i.e., its first variable is'nt self), you can decorate the method using the #staticmethod built-in decorator. If decorators or any of that is not making sense, check out the Wiki, this simple explanation, decorators as syntactic sugar and learn how to write a good one.
>>> class foo(object):
... #staticmethod
... def bar(blah_text):
... print "Unbound method `bar` of Class `foo`"
... return blah_text
...
>>> foobar = foo.bar
>>> foobar("We are the Knights who say 'Ni'!")
Unbound method `bar` of Class `foo`
"We are the Knights who say 'Ni'!"
Bound Methods
These methods are not technically 'bound', but are meant to be binded when called. You just have to point a reference to them and "Wala", you now have a reference to that method. Now you just have to pass a valid instance of that Class:
>>> class foo:
... def __init__(self, bar_value = 'bar'):
... self.bar_value = bar_value
... def bar(self, blah_text):
... return self.bar_value + blah_text
...
>>> bar = foo.bar
>>> bar(foo('We are the Knights who say '), "'Ni'")
"We are the Knights who say 'Ni'"
Edit: As is pointed out in the comments, it seems my usage of 'binding' is wrong. Could somebody with knowledge of it edit/correct my post?
You can call the function with the class name as a parameter, if you do not want to lose self:
class something:
def test(self):
print('Hello')
something.test(something)
#prints "Hello"
Really sorry for the extremely stupid title, but if I know what it is, I wouldn't write here (:
def some_decorator( func ):
# ..
class A:
#some_decorator
def func():
pass
#func.some_decorator # this one here - func.some_decorator ?
def func():
pass
some_decorator decorates func - that's OK. But what is func.some_decorator and how some_decorator becomes a member ( or something else ? ) of func?
P.S. I'm 90% sure, that there's such question here (as this seems something basic), but I don't know how to search it. If there's a exact duplicate, I'll delete this question.
Note : It's not typo, nor accident, that both member functions are named func. The decorator is for overloading: the question is related to Decorating method (class methods overloading)
Remember that the function definition with decorator is equivalent to this:
def func():
pass
func = some_decorator(func)
So in the following lines, func doesn't refer to the function you defined but to what the decorator turned it into. Also note that decorators can return any object, not just functions. So some_decorator returns an object with a method (it's unfortunate that the names some_decorator and func are reused in the example - it's confusing, but doesn't change anything about the concept) that is itself a decorator. As the expression after the # is evaluated first, you still have a reference to the first decorator's method after you defined another plain function func. That decorator is applied to this new function. The full example is then equivalent to this:
class A:
def func():
pass
func = some_decorator(func)
_decorator = func.some_decorator
def func():
pass
func = _decorator(func)
One way to clarify this is to demonstrate it with a concrete example that behaves like this, the builtin property descriptor:
class C(object):
#property
def x(self):
"This is a property object, not a function"
return self._x
#x.setter
def x(self, val):
self._x = val
>>> c = C()
>>> c.x = 1
>>> c.x
1
>>> C.x
<property object at 0x2396100>
>>> C.x.__doc__
'This is a property object, not a function'
>>> C.x.getter.__doc__
'Descriptor to change the getter on a property.'
>>> C.x.setter.__doc__
'Descriptor to change the setter on a property.'
>>> C.x.deleter.__doc__
'Descriptor to change the deleter on a property.'
The first invocation of property (as a decorator) means that x is not a function - it is a property descriptor. A feature of properties is that they allow you to initially define just the fget method, and then provide fset and fdel later by using the property.setter and property.deleter decorators (although since each of these creates a new property object, you do need to make sure to use the same name each time).
Something similar will usually be the case whenever you see code using this kind of pattern. Ideally, the naming of the decorators involved will make it reasonably clear what is going on (e.g. most people seem to grasp the idiom for defining property attributes reasonably easily).