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
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.
How to reference the class itself in python - Stack Overflow
How to reference class variables inside class method
How to reference a class variable in python - Stack Overflow
How can I make a class take an object of the same type as a constructor argument? Currently get unresolved reference...
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.
class Test:
config: Dict[str, str]
parameters: Dict[str, str]
def default(cls)
return cls(
parameters=get_params(),
config=get_config(file="ATTRIBUTE FROM PARAMETERS"
)
# I tried it like this:
class Test:
config: Dict[str, str]
parameters: Dict[str, str]
def default(cls)
return cls(
parameters=get_params(),
config=get_config(file=cls.parameters.config_file)
)
# AttributeError: type object 'Test' has no attribute 'parameters'I am more familiar with C++ so maybe this isn't the python way to do things, but I want to overload the __init__ function of my class "Component" so that I can construct a new object of that type by passing an object of that type that already exists. Reason for doing it this way is that the class has a parent/child structure and so copying the parent requires careful handling of the family tree, I aim to solve this eventually with recursion, using this overloaded constructor as an aid to avoid bloating my copying function with loads of setter lines setting new objects to their appropriate values.
Currently my class that drives from Component (Group) looks like this:
from Components.component import Component, ComponentType
class Group(Component):
def __init__(self,
component_name: str,
):
if component_name is None:
component_name = "New Group"
super().__init__(component_name=component_name, component_type=ComponentType.Group)
self.children: list[Component] = []
def __init__(self, clone: Group): <- This line claims unresolved reference to group, but it is a member of that class!
pass
def add_child(self, new_child: Component):
if new_child not in self.children:
self.children.append(new_child)
else:
print(f"Oh no! {new_child.component_name} is already owned by {self.component_name}!")
def remove_child(self, old_child: Component):
if old_child in self.children:
self.children.remove(old_child)Feel free to tell me I'm handling this totally wrong! It's just the way that came to mind when looking to solve my current problem haha.
You need to store a reference to the object which has the instance of a Y object:
class X(object):
def __init__(self):
self.count = 5
self.y = Y(self) #create a y passing in the current instance of x
def add2(self):
self.count += 2
class Y(object):
def __init__(self,parent):
self.parent = parent #set the parent attribute to a reference to the X which has it
def modify(self):
self.parent.add2()
Example usage:
>>> x = X()
>>> x.y.modify()
>>> x.count
7
Maybe it's possible for you to use class inheritance? For example:
class X(object):
def __init__(self):
self.count = 5
def add2(self):
self.count += 2
class Y(X):
def __init__(self):
super(Y, self).__init__()
def modify(self):
self.add2()
y = Y() # We now create an instance of Y which is a child class of 'super' class X
y.modify()
print(y.count) # 7
You could also make it work by adding a wrapper class that is smarter about what calling whatever it's dealing with.
Since you mentioned in a comment that you're going to need to make the call to one of thewritersmultiple places, I've updated my answer to address this by adding a nested wrapper class to encapsulate the logic of calling the various callable types in one spot. This is a classic example of using OOP to apply the DRY principle.
def save_c(v):
print("c :" + v)
class Writer(object):
@classmethod
def save(cls, t, v):
cls.writerst
@classmethod
def save_a(cls, v):
print("a :" + v)
@staticmethod
def save_b(v):
print("b :" + v)
def _wrapper(writer):
if isinstance(writer, classmethod):
return type('ClassmethodWrapper', (object,), {'__call__':
lambda self, cls, v: writer.__func__(cls, str(v))})()
elif isinstance(writer, staticmethod):
return type('StaticmethodWrapper', (object,), {'__call__':
lambda self, cls, v: writer.__func__(str(v))})()
else:
return type('VanillaWrapper', (object,), {'__call__':
lambda self, cls, v: writer(str(v))})()
writers = list(map(_wrapper, (save_a, save_b, save_c)))
if __name__ == "__main__":
Writer.save(0, [1, 2, 3]) # -> a :[1, 2, 3]
Writer.save(1, [4, 5, 6]) # -> b :[4, 5, 6]
Writer.save(2, [7, 8, 9]) # -> c :[7, 8, 9]
It sounds like you meant to use @staticmethod rather than @classmethod.
For more information, see What is the difference between @staticmethod and @classmethod in Python?