1

I'm working with some LDAP data in python (I'm not great at Python) and trying to organize a class object to hold the LDAP variables. Since it's LDAP data, the end result will be many copies of the same data structure (per user) collected in an iterable list.

I started with hard-coded attribute names for the __slots__ which seemed to be working, but as things progressed I realized those LDAP attributes ought to be immutable constants of some sort to minimize hard coded text/typos. I assigned variables to the __slot__ attributes but it seems this is not such a workable plan:

AttributeError: 'LDAP_USER' object has no attribute 'ATTR_GIVEN_NAME'

Now that I think about it, I'm not actually creating immutable "constants" with the ATTR_ definitions so those values could theoretically be changed during runtime. I can see why Python might be having a problem with this design.

What is a better way to reduce the usage of hard coded text in the code while maintaining a class object which can be instantiated?

ATTR_DN                    = 'dn'
ATTR_GIVEN_NAME            = 'givenName'
ATTR_SN                    = 'sn'
ATTR_EMP_TYPE              = 'employeeType'

class LDAP_USER (object):
   __slots__ = ATTR_GIVEN_NAME, ATTR_DN, ATTR_SN, ATTR_EMP_TYPE

user = LDAP_USER()

user.ATTR_GIVEN_NAME = "milton"
user.ATTR_SN         = "waddams"
user.ATTR_EMP_TYPE   = "collating"

print ("user is " + user.ATTR_GIVEN_NAME)
Kermit
  • 4,922
  • 4
  • 42
  • 74
Server Fault
  • 637
  • 1
  • 6
  • 16
  • Perhaps something like an [enum](https://docs.python.org/3/library/enum.html#module-enum)? – Anoop R Desai Aug 23 '19 at 19:27
  • Also, for immutable constants, [this answer](https://stackoverflow.com/a/2682752/1898437) says there is no way to do it directly. – Anoop R Desai Aug 23 '19 at 19:47
  • Are you wanting to make the `dn, givenName, sn, employeeType` for each instance immutable after being set? – James Aug 23 '19 at 19:51
  • Sort of. I want to use an immutable string to initialize the `__slots__` attributes so I can use one "variable" (constant) to reference all of my LDAP operations. This way, if we ever want `ATTR_EMP_TYPE` to point to the `staffType` LDAP attribute instead of `employeeType`, we can change this in one place and have all the code automatically updated. Perhaps I need to define my class variables differently somehow (not using `__slots__`)? I got in the habit of defining class vars this way since `__slots__` is supposed to be most efficient. This is the first time I've tried it with "constants". – Server Fault Aug 26 '19 at 14:02
  • Maybe this could be summed up as "is there a C macro equivalent in python" ? because what I essentially want to do is : `#define ATTR_DN "dn"` and then use `ATTR_DN` as a reference to a a hash or class variable. – Server Fault Aug 26 '19 at 17:55

1 Answers1

0

With __slots__ defined as [ATTR_GIVEN_NAME, ATTR_DN], the attributes should be referenced using user.givenName and user.dn, since those are the string values in __slots__.

If you want to actually reference the attribute as user.ATTR_GIVEN_NAME then that should be the value in the __slots__ array. You can then add a mapping routine to convert the object attributes to LDAP fields when performing LDAP operations with the object.

Referencing a property not in __slots__ will generate an error, so typos will be caught at runtime.

IronMan
  • 1,854
  • 10
  • 7
  • This answer seems to reflect what I'm finding out through trial-and-error. Maybe it makes more sense to refactor using a regular Dictionary/hash instead of a class. – Server Fault Aug 26 '19 at 18:09