You don't need to reference the class inside itself, using bar instead of Test.bar will work fine.
class Test:
@staticmethod
def bar():
pass
FOO_DICT = {1: bar}
# You can access this outside of the class by simply using Test.FOO_DICT
print(Test.FOO_DICT)
However, there are cases where you really need to use a class in itself. For example
class Test:
@staticmethod
def bar():
pass
def test_with_other_of_same_instance(self, other: Test):
print(other.FOO_DICT)
FOO_DICT = {1: bar}
In this case,
- I want to define a method that accepts an object of the same Test class.
- I want to use python's type hinting to indicate that the expected argument is an instance of Test. This allows me get editor support and also so tools like pylance and mypy can notify me of possible errors if I passed a argument of wrong data type.
As at the time of this writing, I'll get a NameError: name 'Test' is not defined.
This is because by default I can't use a class within itself (It is possible later versions of python will change its default behavior, hence we won't be needing the solution below by that time).
But if you use Python versions from 3.7+ and you can't reference a class within itself, the simple solution came with PEP 563 - Postponed evaluation of annotations. It is implemented by adding a little line of code at the first line of the file
from __future__ import annotations
# other imports or code come afterwards
class Test:
@staticmethod
def bar():
pass
def test_with_other_of_same_instance(self, other: Test):
print(other.FOO_DICT)
FOO_DICT = {1: bar}
So you can use a class within itself in python by simply including that line at the beginning of the file.
Normally, if you use pylance or any similar tool, you get a warning or error display to show you that you imported something and didn't use it. But not in the case of annotations. You don't have to worry about any warning from your editor.
Note that this must occur at the beginning of the file otherwise you get a SyntaxError and versions earlier than 3.7 won't support this.
Answer from Victory Ifebhor on Stack OverflowYou don't need to reference the class inside itself, using bar instead of Test.bar will work fine.
class Test:
@staticmethod
def bar():
pass
FOO_DICT = {1: bar}
# You can access this outside of the class by simply using Test.FOO_DICT
print(Test.FOO_DICT)
However, there are cases where you really need to use a class in itself. For example
class Test:
@staticmethod
def bar():
pass
def test_with_other_of_same_instance(self, other: Test):
print(other.FOO_DICT)
FOO_DICT = {1: bar}
In this case,
- I want to define a method that accepts an object of the same Test class.
- I want to use python's type hinting to indicate that the expected argument is an instance of Test. This allows me get editor support and also so tools like pylance and mypy can notify me of possible errors if I passed a argument of wrong data type.
As at the time of this writing, I'll get a NameError: name 'Test' is not defined.
This is because by default I can't use a class within itself (It is possible later versions of python will change its default behavior, hence we won't be needing the solution below by that time).
But if you use Python versions from 3.7+ and you can't reference a class within itself, the simple solution came with PEP 563 - Postponed evaluation of annotations. It is implemented by adding a little line of code at the first line of the file
from __future__ import annotations
# other imports or code come afterwards
class Test:
@staticmethod
def bar():
pass
def test_with_other_of_same_instance(self, other: Test):
print(other.FOO_DICT)
FOO_DICT = {1: bar}
So you can use a class within itself in python by simply including that line at the beginning of the file.
Normally, if you use pylance or any similar tool, you get a warning or error display to show you that you imported something and didn't use it. But not in the case of annotations. You don't have to worry about any warning from your editor.
Note that this must occur at the beginning of the file otherwise you get a SyntaxError and versions earlier than 3.7 won't support this.
If you want the dictionary to be in the class: define the function first and remove Test:
class Test:
@staticmethod
def bar():
pass
FOO_DICT = {1: bar}
You need @classmethod rather than @staticmethod - a class method will get passed a reference to the class (where a method will get self), so you can look up attributes on it.
class FooBarBaz:
BAR = 123
@classmethod
def getBar(cls):
return cls.BAR
Actually, there is __class__ in python 3:
Python 3.2.3 (v3.2.3:3d0686d90f55, Apr 10 2012, 11:25:50)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> class A:
... @staticmethod
... def foo():
... print(__class__)
...
>>> A.foo()
<class '__main__.A'>
>>>
See http://www.python.org/dev/peps/pep-3135 for the rationale why it has been added.
No idea about how to achieve the same in py2, I guess this is not possible.
Update
In Python 3.11 the module is named typing instead of typing_extensions
from typing import Self
class Node:
"""Binary tree node."""
def __init__(self, left: Self, right: Self):
self.left = left
self.right = right
This might be helpful:
from typing_extensions import Self
class Node:
"""Binary tree node."""
def __init__(self, left: Self, right: Self):
self.left = left
self.right = right
typing_extensions offers a Self class to reference class itself which I think is most elegent way to self-reference(PEP 673).
As others have mentioned, you can also use string literals. But it comes to problem when you have multiple type hints.
# python 3.10
var: str | int
And then you write something like
class Node:
def __init__(self, var: 'Node' | SomeClass):
self.var = var
It will raise a TypeError: unsupported operand type(s) for |: 'str' and 'type'.
While this, as other answers have pointed out, is not a problem due to the dynamic typing, in fact, for Python3, this is a very real issue when it comes to type annotations. And this will not work (note a type annotation of the method argument):
class A:
def do_something_with_other_instance_of_a(self, other: A):
print(type(other).__name__)
instance = A()
other_instance = A()
instance.do_something_with_other_instance_of_a(other_instance)
results in:
def do_something_with_other_instance_of_a(self, other: A):
NameError: name 'A' is not defined
more on the nature of a problem here: https://www.python.org/dev/peps/pep-0484/#the-problem-of-forward-declarations
You can use string literals to avoid forward references

Other way is NOT using python3-style type annotation in such cases,
and this is the only way if you have to keep your code compatible with earlier versions of Python.
Instead, for the sake of getting autocompletion in my IDE (PyCharm), you can docstrings like this:

Update: alternatively, instead of using docstrings, you can use "type: " annotations in a comment. This will also ensure that mypy static type checking will work (mypy doesn't seem to care about docstrings):

If I understand your question correctly, you should be able to reference class A within class A by putting the type annotation in quotes. This is called forward reference.
class A:
# do something
def some_func(self, a: 'A')
# ...
See ref below
- https://github.com/python/mypy/issues/3661
- https://www.youtube.com/watch?v=AJsrxBkV3kc
In Python you cannot reference the class in the class body, although in languages like Ruby you can do it.
In Python instead you can use a class decorator but that will be called once the class has initialized. Another way could be to use metaclass but it depends on what you are trying to achieve.
Add the class after the class is defined:
class Template():
_allowed_types = [str, SafeHtml]
Template._allowed_types.append(Template)
The class body, by necessity, is run before the class object can be created, so the name Template is not defined yet. But you can always alter class attributes after the object has been created.
Another option is using properties to be lazy about the field.
class Test(object):
@property
def allowed(self):
return [str, Test]
t = Test()
print Test in t.allowed
Use a meta class to automatically set it.
def my_meta(name, bases, attrs):
cls = type(name, bases, attrs)
cls.bar = cls
return cls
class Foo(object):
__metaclass__ = my_meta
>>> print Foo.bar
<class '__main__.Foo'>
You could define a class decorator that replaced placeholder strings with the class being defined:
def fixup(cls):
placeholder = '@' + cls.__name__
for k,v in vars(cls).items():
if v == placeholder:
setattr(cls, k, cls)
return cls
@fixup
class Foo(object):
bar = '@Foo'
print('Foo.bar: {!r}'.format(Foo.bar)) # -> Foo.bar: <class '__main__.Foo'>
Another alternative would be to use the __init_subclass__() special method which was introduced in Python 3.6 to create a base class and then derive your class from it instead of the generic object:
class Base(object):
def __init_subclass__(cls, /, **kwargs):
super().__init_subclass__(**kwargs)
cls.bar = cls
class Foo(Base):
pass
print('Foo.bar: {!r}'.format(Foo.bar)) # -> Foo.bar: <class '__main__.Foo'>
Karl's answer is entirely right about everything, but there is certainly a way to make resize act as you're expecting.
Three steps:
- Make a copy of the tree
- Re-initialize the tree so it's the next size larger
Set the enlarged tree's
leftto the copy of the original treedef resize(self,n): while self.size < n: new = self.copy() self.__init__(int(round(self.size, 2)) * 2) self.left = new print("size in resize",self.size) def copy(self): new = tree(1) new.left = self.left new.right = self.right new.size = self.size new.free = self.free return new
Basically, you were trying to do it backwards -- replace self and reuse self for self.left, instead of replacing self.left and reusing self.
self = t
This does not, and cannot be rewritten to, do what you want. There is nothing "special" about the name self in Python; it's just like any other variable (the fact that you have to pass it explicitly to methods should have been your first hint, unlike in languages that treat this as a keyword, should have been your first hint ;) ), and like all other variables, it has reference semantics.
self = t means "from this point onward (until another re-definition or the end of scope), self no longer refers to what that self parameter referred to, but instead to the value that t refers to".
Also, you have a typo in one case of your __init__ method ('rigt'), and I assume that the number of free nodes is supposed to be an invariant something like size - occupied; in which case it would be cleaner to count the occupied nodes and use a method or property to calculate the free ones, instead of trying to update that count on every modification.
(Moreover, what you seem to be trying to do is all kinds of un-Pythonic. In particular, the idea of a container having a specific "allocated size" is strange; that sort of thing normally only matters on the C side of the fence. What do you need a binary tree for? Also, this method isn't going to balance the tree at all. And what use is a tree if none of the nodes store any data?)
Try this:
class Plan(SiloBase):
cost = DataField(int)
start = DataField(System.DateTime)
name = DataField(str)
items = DataCollection(int)
Plan.subPlan = ReferenceField(Plan)
OR use __new__ like this:
class Plan(SiloBase):
def __new__(cls, *args, **kwargs):
cls.cost = DataField(int)
cls.start = DataField(System.DateTime)
cls.name = DataField(str)
cls.items = DataCollection(int)
cls.subPlan = ReferenceField(cls)
return object.__new__(cls, *args, **kwargs)
i've got a metaclass that reads this information and does some setup
Most frameworks that use metaclasses provide a way to resolve this. For instance, Django:
subplan = ForeignKey('self')
Google App Engine:
subplan = SelfReferenceProperty()
The problem with solutions like tacking an additional property on later or using __new__ is that most ORM metaclasses expect the class properties to exist at the time when the class is created.
This is actually a case for defining a metaclass.
I've never actually found a source of information which gives a complete, clear and satisfactory explanation as to what metaclasses are or how they work. I will try to enhance this answer with such information if required but for the time being I am going to stick to a solution for your present problem. I am assuming python 3.
Define an additional class, thus:
class ModelSerializerMeta(serializers.SerializerMetaclass):
def __init__(cls, class_name, base_classes, attributes):
super(ModelSerialiserMeta, cls).__init__(class_name, base_classes, attributes)
Serializer.types[cls.Meta.oid] = [cls.Meta.model, cls]
Then use this as the metaclass of your Serializers, e.g.
class ProfileSerializer(serializers.ModelSerializer, metaclass=ModelSerializerMeta):
class Meta:
oid = 'profile'
model = Profile
fields = ['login', 'status']
Better yet, create some superclass for all your model serializers, assign the metaclass there, make all of your serializers inherit from that superclass which will then use the metaclass throughout.
Metaclasses are definitely the right answer unless your code can require python >= 3.6. Starting with 3.6 there is a new feature called the __init_subclass__ hook.
So you can do something like
class foo:
@classmethod
def __init_subclass__(cls, *args, **kwargs):
Serializers.register_class(cls)
Whenever a child of Foo is defined, the __init_subclass__ method on Foo will be called, passing in the child class reference as cls.
class Point(object):
ZERO = None
def __init__(self, x, y):
self.x = x
self.y = y
Point.ZERO = Point(0,0)
ZERO in the class definition is not needed but I'm using it because my IDE is not able to find the class variable for code completion.
You can try using a setter method (setReference):
class SomeClassReference(object):
def __init__(self):
self.reference = None
class MyClass(object):
def __init__(self):
self.a = SomeClassReference()
def setReference(self):
self.a.reference = MyClass
There is no generic way for a function to refer to itself. Consider using a decorator instead. If all you want as you indicated was to print information about the function that can be done easily with a decorator:
from functools import wraps
def showinfo(f):
@wraps(f)
def wrapper(*args, **kwds):
print(f.__name__, f.__hash__)
return f(*args, **kwds)
return wrapper
@showinfo
def aa():
pass
If you really do need to reference the function, then just add it to the function arguments:
def withself(f):
@wraps(f)
def wrapper(*args, **kwds):
return f(f, *args, **kwds)
return wrapper
@withself
def aa(self):
print(self.__name__)
# etc.
Edit to add alternate decorator:
You can also write a simpler (and probably faster) decorator that will make the wrapped function work correctly with Python's introspection:
def bind(f):
"""Decorate function `f` to pass a reference to the function
as the first argument"""
return f.__get__(f, type(f))
@bind
def foo(self, x):
"This is a bound function!"
print(self, x)
>>> foo(42)
<function foo at 0x02A46030> 42
>>> help(foo)
Help on method foo in module __main__:
foo(self, x) method of builtins.function instance
This is a bound function!
This leverages Python's descriptor protocol: functions have a __get__ method that is used to create bound methods. The decorator simply uses the existing method to make the function a bound method of itself. It will only work for standalone functions, if you wanted a method to be able to reference itself you would have to do something more like the original solution.
http://docs.python.org/library/inspect.html looks promising:
import inspect
def foo():
felf = globals()[inspect.getframeinfo(inspect.currentframe()).function]
print felf.__name__, felf.__doc__
you can also use the sys module to get the name of the current function:
import sys
def bar():
felf = globals()[sys._getframe().f_code.co_name]
print felf.__name__, felf.__doc__
If you want your method to access a class variable, you need to access it via the class name or via self. Either one should work:
class dli:
switch = dlipower.PowerSwitch()
# no need for an empty __init__ method
def PowerOn(self, port):
outlet = dlipower.Outlet(dli.switch)
outlet.on(port)
Or:
class dli:
switch = dlipower.PowerSwitch()
def PowerOn(self, port):
outlet = dlipower.Outlet(self.switch)
outlet.on(port)
This still recreates the outlet every time you call PowerOn, but perhaps that's cheap...
You don't really need a class for this. The class variable switch is just a global variable tucked away in the class namespace. Since you don't have any other attributes (either class attributes or instance attributes), it might be simpler to just use an actual global instead:
# no dli class needed any more, just use top level variables and functions!
_switch = dlipower.PowerSwitch() # create a global PowerSwitch
def PowerOn(port):
outlet = dlipower.Outlet(_switch)
outlet.on(port)
I've used a name with an underscore for the global variable. That tells any other programmers looking at the code that it is an internal implementation detail, not part of your module's API. It's not "private" in the way some other programming languages mean (where the compiler prevents other code from accessing it), but it's Python's version of being private (where other code is discouraged, but not prevented from accessing internal stuff).
Speaking of naming conventions, you might want to change yours. The most common convention for Python code is to use CaptializedNames only for classes, and lower_case_names_with_underscores for most other things (functions, variables, etc.). Using a different convention isn't wrong per se, but it may make it more difficult for others to read your code.
If you're trying to pass a specific instance of a PowerSwitch object into the Outlet object you're instantiating within the PowerOn function, pass it into the function as an argument, as such:
def PowerOn(self, port, switch):
outlet = dlipower.Outlet(switch)
outlet.on(port)
Then, whenever you want to instantiate a new Outlet, just instantiate the PowerSwitch before the function call, and include it as an argument.
In order to reference a variable from outside a given function within a function, that variable must either be global (created outside any function or class), a class variable (created outside a function within a class), a variable created within the function, or an argument provided with the function.
This is not possible, since everything you define in a class becomes a valid member only in an instance of that class, unless you define a method with @staticmethod, but there is no such property for a class.
So, this won't work either:
class Foo(object):
x = 10
class A(object):
pass
class B(object):
other = x
This will work, but it is not what you intended:
class Foo(object):
x = 10
class A(object):
pass
class B(object):
def __init__(self):
self.other = Foo.A
f = Foo()
print(f.B().other)
The output is:
<class '__main__.Foo.A'>
The reason this works is that the methods (in this case __init__) are evaluated when the object is created, while assignment before the __init__ are evaluated while the class is read and interpreted.
You can get about the same thing you want by simply define all the classes inside a module of their own. The importing the module, makes it an object whose fields are the classes you define in it.
I don't think it's good object oriented practice, but you can set inner class attributes at the outer class scope. For instance.
class Class2:
class Labels:
c2l1 = 'label 1'
c2l2 = 'label 2'
class Params:
pass
# p1 = None
# p2 = None
# p3 = None
Params.p1 = Labels.c2l2
Params.p2 = 1234
print(Class2.Params.p1)
print(Class2.Params.p2)
# print(Class2.Params.p3)
label 2
1234
These are all class attributes, but instance attributes should work similarly.