Does Python have class prototypes (or forward declarations)?
In Python you don't create a prototype per se, but you do need to understand the difference between "class attributes" and instance-level attributes. In the example you've shown above, you are declaring a class attribute on class B, not an instance-level attribute.
This is what you are looking for:
class B():
def __init__(self):
self.c = C()
Does Python support forward declaration in class?
The problem is that you did not understand python classes, you are referring to a global scoped name feed_pet
but you meant to call the function within the class, for that you need to use self
, check the changes below:
class Animal:
def __init__(self):
self.action = {'feed':self.feed_pet}
def do_action(self, a):
self.action[a]() //use self also for access instance attributes
def feed_pet(self):
print('Gives some food')
# main.py
from animal import *
my_pet = Animal()
my_pet.do_action('feed')
For making it clear, Does Python support forward declaration in class?
There is no need for forward declarations in python, unlike C you can redefine any object as many times as you want, python will keep the last one of them as the live ones. Also, as it does not have static typing at compile time, you can use any variable as any type, hence you don't need to declare anything to use it, just at runtime have to be in the same scope.
How can I forward-declare/prototype a function in Python?
Python does not have prototyping because you do not need it.
Python looks up globals at runtime; this means that when you use writeHello
the object is looked up there and then. The object does not need to exist at compile time, but does need to exist at runtime.
In C++ you need to prototype to allow two functions to depend on one another; the compiler then can work out that you are using the second, later-defined function. But because Python looks up the second function at runtime instead, no such forward definition is needed.
To illustrate with an example:
def foo(arg):
if not arg:
return bar()
def bar(arg=None):
if arg is not None:
return foo(arg)
Here, both foo
and bar
are looked up as globals when the functions are called, and you do not need a forward declaration of bar()
for Python to compile foo()
successfully.
Use global variables defined by one class within the class
Following code gives me error,
SyntaxError: invalid syntax
becauseLAND
is not defined
No, you get a SyntaxError
because an assignment a = b
(in your specific case
self.id = LAND.id
) is not an expression, wich means that it does not produce a value which you would be able to return
.
Your code works just fine when you change the =
to a ==
, which is what I assume you want. Alternatively (I'm a bit unsure what is supposed to happen in your code), you could write two lines:
self.id = LAND.id
return self.id
Anyway, the problem here is not that LAND
is not defined when is_free
is created. That's not a problem, because nobody is calling is_free
yet. The problem is that you probably thought (because you seem to come from a C background ) that an assignment with =
produces a value, which is not the case in Python.
Python forward-declaration of functions inside classes
First, in class B
, the function foo()
is called before being declared. A
does not have this problem because foo()
is only called when the class is instantiated--after the function foo is defined.
For your second question, y.a will not work because you did not say self.a = foo('stirng')
. a = foo('stirng')
only creates the variable a in the scope of __ init __
.
An ideal __ init __
function assigns variables to the instance self
.
python class inheritance order
This happens because python gets interpreted Top-To-Bottom. In the line where you define class A(B)
in your first example, class B
was not yet read by python.
In your second example, B
is already known in the line class A(B)
. That's why it runs.
How do I forward-declare a function to avoid `NameError`s for functions defined later?
If you don't want to define a function before it's used, and defining it afterwards is impossible, what about defining it in some other module?
Technically you still define it first, but it's clean.
You could create a recursion like the following:
def foo():
bar()
def bar():
foo()
Python's functions are anonymous just like values are anonymous, yet they can be bound to a name.
In the above code, foo()
does not call a function with the name foo, it calls a function that happens to be bound to the name foo
at the point the call is made. It is possible to redefine foo
somewhere else, and bar
would then call the new function.
Your problem cannot be solved because it's like asking to get a variable which has not been declared.
How can two python classes declare references each other and itself?
[Answer edited following discussion in the comments.]
If you want a recursive class definition with an __init__
method, then a proper implementation will depend on your goals, but PirateNinjas's answer using Optional
is probably what you want. However, if you really need static class members, you can initialize them after declaring both classes:
class A:
a: 'A'
b: 'B'
class B:
a: 'A'
b: 'B'
A.a = A()
A.b = B()
B.a = A()
B.b = B()
Can I somehow reference a Python class that is declared later than the class from which I need to reference without changing their order?
When using pydantic.ForwardRef
, you need to call update_forward_refs
on classes that have forward references to update them. So add
Role.update_forward_refs()
after User
is defined.
This will all be unnecessary if PEP 649 is accepted.
Related Topics
How to Remove Specific Tag/Sticker/Object from Images Using Opencv
Beautiful Soup 4 Find_All Don't Find Links That Beautiful Soup 3 Finds
Split Views.Py in Several Files
How to Change the String Representation of a Python Class
Is There a Difference Between Using a Dict Literal and a Dict Constructor
How to Send an Xml Body Using Requests Library
How to Resize an Image with Opencv2.0 and Python2.6
How to Convert Escaped Characters
Split String Based on a Regular Expression
Check If a Given Key Already Exists in a Dictionary and Increment It
Unbalanced Data and Weighted Cross Entropy
What Is the Best Approach to Change Primary Keys in an Existing Django App