Home > Software design >  How to check if class has attribute that are other classes
How to check if class has attribute that are other classes

Time:04-07

Consider the following Python code:

from pydantic import BaseModel

class customer_s3_buckets_object(BaseModel):
    class s3_bucket(BaseModel):
        access_key: str = None
        secret_key: str = None
        region: str = None
        name: str = None
    encryption_bucket: s3_bucket = s3_bucket()
    file_transfer_bucket: s3_bucket = s3_bucket()
    holding_bucket: s3_bucket = s3_bucket()

class customer_object(BaseModel):
    s3_buckets: customer_s3_buckets_object = customer_s3_buckets_object()

Assume further I have a variable my_customer that is of type customer_object. Customers may have any combination of the 3 s3 buckets. For example, some customers may only have a holding_bucket but no file_transfer_bucket and encryption_bucket.

When the customer does not have a bucket, then that attribute is set to None by another function that initializes my_customer.

So for example, an instance of my_customer could have:

  • my_customer.s3_buckets.encryption_bucket set to a valid value
  • my_customer.s3_buckets.file_transfer_bucket set to None
  • my_customer.s3_buckets.holding_bucket set to None

Is there a way I can do the following test without the code crashing (and not using a try / except block)?

if s3_buckets.file_transfer_bucket.access_key in my_customer
  print("Yes, customer has file transfer bucket access key")

I'm just looking for a convenient way of doing this.

CodePudding user response:

Easiest way is to test for the case where s3_buckets.file_transfer_bucket is None before accesing its access_key attribute:

if s3_buckets.file_transfer_bucket is None:
   print('No file transfer bucket')
elif s3_buckets.file_transfer_bucket.access_key in my_customer:
    # file_transfer_bucket is guaranteed to not be None
    print("Yes, customer has file transfer bucket access key")

You may think this is tedious, and would prefer if both of these operations happened "automagically" in a single line. But the test needs to be done. Otherwise you won't be able to differentiate between the if clause failing because file_transfer_bucket is None, or because its access_key is not in my_customer.

You can "hide" this behavior somewhat by implementing a get_access_key() method, using properties, etc. But at some point the test needs to be done because None is a valid value for the file_transfer_bucket - even if it is done internally in one of your classes.

Perhaps a better alternative would be for clients to always have a s3_bucket instance as the file_transfer_bucket attribute, and setting its access_key to None when that bucket is "invalid" - but only you knows that for sure, since we don't know what your code is trying to achieve.

  • Related