indirectly accessing python instance attribute without using dot notation

  • Last Update :
  • Techknowledgy :

Do:

  getattr(parent, collection).append(child)

Suggestion : 2

Given a couple of simple tables in sqlalchemy which have a simple one to many relationship, I am trying to write a generalized function to add children to the relationship collection. The tables look like this:,Ok. so far so good. In reality, my app is going to have several tables with relationships. My issue arises when I try to generalize this out to a function to handle arbitrary relationships. Here'e what I wrote (note, add_item() is just a method which wraps an object construction with a try/except to handle IntegrityError's):, In Python, almost every entity is traded as an Object. And knowing this is fundamental to grasp the significance of dot (.) notation. What is the Dot Notation? In simple words, the dot (.) notation is a way to access the attribute and methods of each method of instances of different object classes. ,So my question, is how can I add an item to the collection by key word instead of using 'dot' notation?


class StockItem(Base):     __tablename__ = 'stock_items'     stock_id = Column(Integer, primary_key=True)     description = Column(String, nullable=False, unique=True)     department = Column(String)     images = relationship('ImageKey', backref='stock_item', lazy='dynamic')     def __repr__(self):         return '<StockItem(Stock ID:{}, Description: {}, Department: {})>'.\             format(self.stock_id, self.description, self.department) class ImageKey(Base):     __tablename__ = 'image_keys'     s3_key = Column(String, primary_key=True)     stock_id = Column(Integer, ForeignKey('stock_items.stock_id'))     def __repr__(self):         return '<ImageKey(AWS S3 Key: {}, Stock Item: {})>'.\             format(self.s3_key, self.stock_id) 

  getattr(parent, collection).append(child)
class StockItem(Base):__tablename__ = 'stock_items'stock_id = Column(Integer, primary_key=True)description = Column(String, nullable=False, unique=True)department = Column(String)images = relationship('ImageKey', backref='stock_item', lazy='dynamic')def __repr__(self):  return '<StockItem(Stock ID:{}, Description: {}, Department: {})>'.\ format(self.stock_id, self.description, self.department)   class ImageKey(Base):__tablename__ = 'image_keys's3_key = Column(String, primary_key=True)stock_id = Column(Integer, ForeignKey('stock_items.stock_id'))def __repr__(self):  return '<ImageKey(AWS S3 Key: {}, Stock Item: {})>'.\ format(self.s3_key, self.stock_id) 
item = StockItem(stock_id = 42, description = 'Frobnistication for Foozlebars', department = 'Books') image = ImageKey(s3_key = 'listings/images/Frob1.jpg', stock_id = 42) item.images.append(image)
@session_manager def _add_collection_item(self, Parent, Child, key, collection, session = None, ** kwargs): ""
"Add a Child object to the collection object of Parent."
""
child = self.add_item(Child, session = session, ** kwargs) parent = session.query(Parent).get(key) parent.collection.append(child) # This line obviously throws error.session.add(parent)
db._add_collection_item(StockItem, ImageKey, 42, 'images', s3_key = 'listings/images/Frob1.jpg', stock_id = 42)

Suggestion : 3

Function objects also support getting and setting arbitrary attributes, which can be used, for example, to attach metadata to functions. Regular attribute dot-notation is used to get and set such attributes. Note that the current implementation only supports function attributes on user-defined functions. Function attributes on built-in functions may be supported in the future.,Some of the type descriptions below contain a paragraph listing ‘special attributes.’ These are attributes that provide access to the implementation and are not intended for general use. Their definition may change in the future.,Methods also support accessing (but not setting) the arbitrary function attributes on the underlying function object.,Multiple inheritance with multiple slotted parent classes can be used, but only one parent is allowed to have attributes created by slots (the other bases must have empty slot layouts) - violations raise TypeError.

def __hash__(self):
   return hash((self.name, self.nick, self.color))
import sys
from types
import ModuleType

class VerboseModule(ModuleType):
   def __repr__(self):
   return f 'Verbose {self.__name__}'

def __setattr__(self, attr, value):
   print(f 'Setting {attr}...')
super().__setattr__(attr, value)

sys.modules[__name__].__class__ = VerboseModule
class Philosopher:
   def __init_subclass__(cls, /, default_name, **kwargs):
      super().__init_subclass__( ** kwargs) cls.default_name = default_name

      class AustralianPhilosopher(Philosopher, default_name = "Bruce"):
      pass
class A:
   x = C() # Automatically calls: x.__set_name__(A, 'x')
class A:
   pass

c = C()
A.x = c # The hook is not called
c.__set_name__(A, 'x') # Manually invoke the hook
class Meta(type):
   pass

class MyClass(metaclass = Meta):
   pass

class MySubclass(MyClass):
   pass

Suggestion : 4

When you try to access an attribute from an instance of a class, it first looks at its instance namespace. If it finds the attribute, it returns the associated value. If not, it then looks in the class namespace and returns the attribute (if it’s present, throwing an error otherwise). For example:,As it turns out, we were both wrong. The real answer lay in understanding the distinction between Python class attributes and Python instance attributes.,In that case, the instance namespace takes supremacy over the class namespace. If there is an attribute with the same name in both, the instance namespace will be checked first and its value returned.,The instance namespace takes supremacy over the class namespace: if there is an attribute with the same name in both, the instance namespace will be checked first and its value returned. Here’s a simplified version of the code (source) for attribute lookup:

I took a deep breath and started typing. After a few lines, I had something like this:

class Service(object):
   data = []

def __init__(self, other_data):
   self.other_data = other_data
   ...

For reference, and to give you an idea of what I was going for, here’s how I amended the code:

class Service(object):

   def __init__(self, other_data):
   self.data = []
self.other_data = other_data
   ...

Let’s use a Python class example to illustrate the difference. Here, class_var is a class attribute, and i_var is an instance attribute:

class MyClass(object):
   class_var = 1

def __init__(self, i_var):
   self.i_var = i_var

Depending on the context, you may need to access a namespace using dot syntax (e.g., object.name_from_objects_namespace) or as a local variable (e.g., object_from_namespace). As a concrete example:

class MyClass(object):
   # # No need
for dot syntax
class_var = 1

def __init__(self, i_var):
   self.i_var = i_var

# # Need dot syntax as we 've left scope of class namespace
MyClass.class_var
# # 1

When you try to access an attribute from an instance of a class, it first looks at its instance namespace. If it finds the attribute, it returns the associated value. If not, it then looks in the class namespace and returns the attribute (if it’s present, throwing an error otherwise). For example:

foo = MyClass(2)

# # Finds i_var in foo 's instance namespace
foo.i_var
# # 2

# # Doesn 't find class_var in instance namespace…
# # So look 's in class namespace (MyClass.__dict__)
foo.class_var
# # 1

If a class attribute is set by accessing the class, it will override the value for all instances. For example:

foo = MyClass(2)
foo.class_var
# # 1
MyClass.class_var = 2
foo.class_var
# # 2

If a Paython class variable is set by accessing an instance, it will override the value only for that instance. This essentially overrides the class variable and turns it into an instance variable available, intuitively, only for that instance. For example:

foo = MyClass(2)
foo.class_var
# # 1
foo.class_var = 2
foo.class_var
# # 2
MyClass.class_var
# # 1

Avoided using the empty list (a mutable value) as our “default”:

class Service(object):
   data = None

def __init__(self, other_data):
   self.other_data = other_data
   ...

Storing constants. As class attributes can be accessed as attributes of the class itself, it’s often nice to use them for storing Class-wide, Class-specific constants. For example:

class Circle(object):
   pi = 3.14159

def __init__(self, radius):
   self.radius = radius

def area(self):
   return Circle.pi * self.radius * self.radius

Circle.pi
# # 3.14159

c = Circle(10)
c.pi
# # 3.14159
c.area()
# # 314.159

Defining default values. As a trivial example, we might create a bounded list (i.e., a list that can only hold a certain number of elements or fewer) and choose to have a default cap of 10 items:

class MyClass(object):
   limit = 10

def __init__(self):
   self.data = []

def item(self, i):
   return self.data[i]

def add(self, e):
   if len(self.data) >= self.limit:
   raise Exception("Too many elements")
self.data.append(e)

MyClass.limit
# # 10

We could then create instances with their own specific limits, too, by assigning to the instance’s limit attribute.

foo = MyClass()
foo.limit = 50
# # foo can now hold 50 elements— other instances can hold 10

Suggestion : 5

Use dot notation or getattr() function to get the value of a class attribute.,A class is an object which is an instance of the type class.,Use dot notation or setattr() function to set the value of class attribute.,Another way to get the value of a class variable is to use the getattr() function. The getattr() function accepts an object and a variable name. It returns the value of the class variable. For example:

When you define a class using the class keyword, Python creates an object with the name the same as the class’s name. For example:

.wp - block - code {
      border: 0;
      padding: 0;
   }

   .wp - block - code > div {
      overflow: auto;
   }

   .shcb - language {
      border: 0;
      clip: rect(1 px, 1 px, 1 px, 1 px); -
      webkit - clip - path: inset(50 % );
      clip - path: inset(50 % );
      height: 1 px;
      margin: -1 px;
      overflow: hidden;
      padding: 0;
      position: absolute;
      width: 1 px;
      word - wrap: normal;
      word - break: normal;
   }

   .hljs {
      box - sizing: border - box;
   }

   .hljs.shcb - code - table {
      display: table;
      width: 100 % ;
   }

   .hljs.shcb - code - table > .shcb - loc {
      color: inherit;
      display: table - row;
      width: 100 % ;
   }

   .hljs.shcb - code - table.shcb - loc > span {
      display: table - cell;
   }

   .wp - block - code code.hljs: not(.shcb - wrap - lines) {
      white - space: pre;
   }

   .wp - block - code code.hljs.shcb - wrap - lines {
      white - space: pre - wrap;
   }

   .hljs.shcb - line - numbers {
      border - spacing: 0;
      counter - reset: line;
   }

   .hljs.shcb - line - numbers > .shcb - loc {
      counter - increment: line;
   }

   .hljs.shcb - line - numbers.shcb - loc > span {
      padding - left: 0.75 em;
   }

   .hljs.shcb - line - numbers.shcb - loc::before {
      border - right: 1 px solid #ddd;
      content: counter(line);
      display: table - cell;
      padding: 0 0.75 em;
      text - align: right; -
      webkit - user - select: none; -
      moz - user - select: none; -
      ms - user - select: none;
      user - select: none;
      white - space: nowrap;
      width: 1 % ;
   }
class HtmlDocument:
   passCode language: Python(python)

This example defines the HtmlDocument class and the HtmlDocument object. The HtmlDocument object has the __name__ property:

print(HtmlDocument.__name__) # HtmlDocumentCode language: Python(python)

And the HTMLDocument has the type of type:

print(type(HtmlDocument)) # <class 'type'>Code language: Python (python)

The following example adds the extension and version class variables to the HtmlDocument class:

class HtmlDocument:
   extension = 'html'
version = '5'
Code language: Python(python)

To get the values of class variables, you use the dot notation (.). For example:

print(HtmlDocument.extension) # html
print(HtmlDocument.version) # 5 Code language: Python(python)

Suggestion : 6

Once you have created an instance, you can access its attributes (data and methods) using the dot (.) operator. For example:,There is no difference between instance attributes created by assigning to attributes and those created by explicitly binding an entry in z.__dict__.,Finally, note that the class statement does not immediately create any instance of the new class, but rather defines the set of attributes shared by all instances when you later create instances by calling the class.,When a class overrides __getattribute__, attribute accesses on instances of the class become slow, since the overriding code executes on every such attribute access.

The class statement is the most common way to create a class object. class is a single-clause compound statement with the following syntax:

class classname(base - classes):
   statement(s)

You normally specify an attribute of a class object by binding a value to an identifier within the class body. For example:

class C1(object):
   x = 23
print(C1.x) # prints: 23

You can also bind or unbind class attributes outside the class body. For example:

class C2(object): pass
C2.x = 23
print(C2.x) # prints: 23

The class statement implicitly sets some class attributes. Attribute __name__ is the classname identifier string used in the class statement. Attribute __bases__ is the tuple of class objects given as the base classes in the class statement. For example, using the class C1 we just created:

print(C1.__name__, C1.__bases__)
# prints: C1 (<type 'object'>,)

However, in statements in methods defined in a class body, references to attributes of the class must use a fully qualified name, not a simple name. For example:

class C4(object):
   x = 23
def amethod(self):
   print(C4.x) # must use C4.x or self.x, not just x!

Here’s an example of a class that includes a method definition:

class C5(object):
   def hello(self):
   print('Hello')

A descriptor is any object whose class supplies a special method named __get__. Descriptors that are class attributes control the semantics of accessing and setting attributes on instances of that class. Roughly speaking, when you access an instance attribute, Python gets the attribute’s value by calling __get__ on the corresponding descriptor, if any. For example:

class Const(object): # an overriding descriptor, see later
def __init__(self, value):
   self.value = value
def __set__(self, * _): # ignore any attempt at setting
pass
def __get__(self, * _): # always
return the constant value
return self.value

class X(object):
   c = Const(23)

x = X()
print(x.c) # prints: 23
x.c = 42
print(x.c) # prints: 23

To create an instance of a class, call the class object as if it were a function. Each call returns a new instance whose type is that class:

an_instance = C5()

When a class defines or inherits a method named __init__, calling the class object implicitly executes __init__ on the new instance to perform any needed per-instance initialization. Arguments passed in the call must correspond to the parameters of __init__, except for parameter self. For example, consider:

class C6(object):
   def __init__(self, n):
   self.x = n

Here’s how you can create an instance of the C6 class:

another_instance = C6(42)

You can give an instance object an arbitrary attribute by binding a value to an attribute reference. For example:

class C7: pass
z = C7()
z.x = 23
print(z.x) # prints: 23

Creating an instance implicitly sets two instance attributes. For any instance z, z.__class__ is the class object to which z belongs, and z.__dict__ is the mapping that z uses to hold its other attributes. For example, for the instance z we just created:

print(z.__class__.__name__, z.__dict__) # prints: C7 {
   'x': 23
}

When a class defines or inherits a method named __init__, calling the class object implicitly executes __init__ on the new instance to perform any needed per-instance initialization. Arguments passed in the call must correspond to the parameters of __init__, except for parameter self. For example, consider:

class C6(object):
   def __init__(self, n):
   self.x = n

Here’s how you can create an instance of the C6 class:

another_instance = C6(42)

Suggestion : 7

Last Updated : 04 May, 2020

Output:

hello my name is: HARRY
my roll number is: 1001
HARRY

Suggestion : 8

The ‘types’ Python module can be used to create classes and subclasses dynamically:,The ontology class attribute can be used to associate your class to the given ontology. If not specified, this attribute is inherited from the parent class (in the example below, the parent class is Thing, which is defined in the ‘owl’ ontology).,The .instances() class method can be used to iterate through all Instances of a Class (including its subclasses). It returns a generator.,Subclasses can be created by inheriting an ontology class. Multiple inheritance is supported.

>>> from owlready2
import *

>>>
onto = get_ontology("http://test.org/onto.owl")

   >>>
   class Drug(Thing):
   ...namespace = onto
>>> onto = get_ontology("http://test.org/onto.owl")

   >>>
   with onto:
   ...class Drug(Thing):
   ...pass
>>> print(Drug.iri)
http: //test.org/onto.owl#Drug
>>> class DrugAssociation(Drug): # A drug associating several active principles
   ...pass
>>> print(DrugAssociation.is_a)[onto.Drug]
>>> print(Drug.subclasses())[onto.DrugAssociation]