Access Class Variable from Instance

Can I access a class variable from an instance?

Use self.__class__.classAttr. This should work for both old & new style classes.

How to access class variable inside methods of that class in python?

There are two ways to access it

first: self.__class__.PAD_token

second: self.PAD_token

If you just need to access class variables, the first one is recommended

Is accessing class variables via an instance documented?

Refs the Classes and Class instances parts in the Python data model documentation

A class has a namespace implemented by a dictionary object. Class
attribute references are translated to lookups in this dictionary,
e.g., C.x is translated to C.__dict__["x"] (although for new-style classes in particular there are a number of hooks which allow for other means of locating attributes).

...

A class instance is created by calling a class object (see above). A
class instance has a namespace implemented as a dictionary which is
the first place in which attribute references are searched. When an
attribute is not found there, and the instance’s class has an
attribute by that name, the search continues with the class
attributes.

Generally, this usage is fine, except the special cases mentioned as "for new-style classes in particular there are a number of hooks which allow for other means of locating attributes".

Can I access class variables using self?

Assigning remote to self in __init__ means that instance.remote is found first when you access it through self (granted no descriptors are around). To get both options, access either from self or from type(self), that is, either from the instance or the class:

def print_remote(self):
print(type(self).remote) # class remote
print(self.remote) # instance remote

type(self).remote is essentially equivalent to self.__class__.remote but, in general, you should avoid grabbing dunder names (__*__) when there's a built in that does it for you (type in this case)

These live in different dictionaries and are different variables. self.remote lives in the instance dict while class.remote in the class dict.

>>> Foo().__dict__['remote']
True
>>> Foo.__dict__['remote']
False

When you access through cls with a classmethod (or type(self) in a normal method) you'll get the class one, when you access through self you get the instance one.

In Python, do assignment operators access class or instance variables when passed as a default value in a class method definition?

The only way you can access an instance variable is as an attribute of self.

When you just refer to var, that's never an instance variable; it's always a local, enclosing, global, or builtin variable.


In your method definition:

def lookup(self, var=var):
print(var)

… you have a parameter named var. Parameters are local variables. The print(var) inside the body prints that local variable.

What about this?

def lookup(self, var=var):
var = var

Again, var is a local variable—a parameter. So, you're just assigning the current value of that local variable to the same variable. Which has no useful effect, but of course it's perfectly legal.


Where does the parameter's value come from? At function call time, if you pass an argument, that argument gets bound to the parameter; if you don't, it gets filled in with the default value.

OK, so where does the default value come from?

At function definition time (when the def statement is executed), var is looked up in the current scope—that is, the body of the class definition—and its value is stored as a default in the function object (it should be visible as foo.lookup.__defaults__[0]).

So, the default value is "value goes here".

Notice that it's not a closure capture or other reference to the class attribute. When the class statement is executed, it uses that same class body namespace to build the class's attributes, so you end up with foo.var as another name for the same value that's in foo.lookup.__defaults__[0]. But they're completely independent names for that value; you can reassign foo.var = 3, and the default value for lookup's parameter will still be "value goes here".


So, to answer your specific questions:

Will it store it in the class variable, the instance variable, or a new variable with the same name?

None of the above. It stores it in a local variable that already exists, because it's a parameter.

Will it get the class variable, instance variable, or the method's variable?

If by "the method's variable" you mean the parameter, it's the last one.

How do I explicitly reference these variables?

The same way you explicitly reference anything else:

  • var is a local-enclosing-global-or-builtin variable.
  • self.var is an instance attribute, or a class attribute if there is no instance attribute.
  • type(self).var is a class attribute, even if there is an instance attribute.

Using class method to access class variable within a class

self.name by default refers to cls.name

if you set it it only sets it for that instance however

self.name = "bob"

now overrides the class level name

just the same for methods as well

class Foo:
@staticmethod
def hello():
print("Hi There From Foo!")
def __init__(self):
self.hello() #this works

Foo.hello() # this also works
Foo() # print from in the init

How to access class instance variable as method parameter in Python 3?

The default argument value is evaluated at the time of the class definition, so it is not possible to define a default per-instance. The method object is created, with a single default value, at the time of class definition.

The typical way to achieve what you want would be like this:

def caller(self, test=None):
if test is None
test = self.test
...

How to access class method and class variable from a class to another class's instance method in Python?

For your code, either of the three way works fine.

But in general, I would say using the class name to access class methods and class variables is the safest way to ensure you are accessing the right methods/variables.

For example,

1.If you have another info() in class C whether it's a class method or an instance method,

self.info()

will call that method defined in class C, NOT the one in class A

2.If the order of inheritance is different as to class C(B, A), and you have another info() in class B whether it's a class method or an instance method,

super().info()

will call that method defined in class B, NOT the one in class A

How to access class instance attributes indirectly?

Use the getattr() function to get an attribute of an object if you have its name in a variable, and setattr() to set it in similar circumstances.

class Test:
def __init__(self):
self.testval = 0

test=Test()
A = "testval"

print(test.testval)
setattr(test, A, 1)
print(test.testval)

You can also define your class to have a __setitem__ method; then you can use dictionary-like syntax to set attributes.

class Test:

def __init__(self):
self.testval = 0

def __setitem__(self, key, value):
setattr(self, key, value)

test=Test()
A = "testval"

print(test.testval)
test[A] = 1
print(test.testval)

Finally (well, there are other ways you can handle this, but I'm only going to mention one more)... finally, you could make a class that holds a reference to an object and an attribute name. This is convenient when you want to pass around such references.

class Test:
def __init__(self):
self.testval = 0

class IndirectAttribute:

def __init__(self, obj, attr):
self.obj = obj
self.attr = attr

def set(self, value):
setattr(self.obj, self.attr, value)

test = Test()
A = IndirectAttribute(test, "testval")

print(test.testval)
A.set(1)
print(test.testval)


Related Topics



Leave a reply



Submit