Python How to Inherit an attribute from another class without using subclass

  • Thread starter Thread starter Arman777
  • Start date Start date
  • Tags Tags
    Class
Click For Summary
The discussion focuses on how to manage user attributes in a Python program without creating a subclass for an admin. The original code assigns an instance of the Admin class to each User, which complicates privilege management. Suggestions include adding an admin status directly to the User class or passing a User object to the Admin class. A proposed solution involves using properties to determine admin status based on user attributes. Ultimately, the consensus is that defining Admin as a subclass of User simplifies the design and allows for better attribute management.
  • #31
pbuk said:
But beware that just because this is possible doesn't mean its a good idea:
Yeah it seems a bit awkward.. But yes this is what I was looking for.

pbuk said:
are you familiar with the concept of an 'anti-pattern'?
Nope, never heard.
pbuk said:
You can't: first_name is a property of a User object not an Admin object. What you can do as I highlighted previously is make a user a property of an Admin object, then you can use self.user.first_name in an Admin object.
I tried that but it did not worked that time, maybe I did something wrong. But this time it works
 
Technology news on Phys.org
  • #32
It seems that anti-pattern is a bad idea to solve/design a problem
 
  • Like
Likes pbuk
  • #33
Python:
class User():
    def __init__(self, first_name, last_name, gender, age, country):
        """
        Description of the user
        """
        self.first_name = first_name
        self.last_name = last_name
        self.gender = gender
        self.age = age
        self.country = country
        self.login_attempts = 0

    def describe_user(self):
        """
        Printing the users information, if the user is admin do not give any information
        """
        if self.first_name == "Arman" and self.last_name == "Cam":
            print("This information is classified")
        else:
            print("First Name: ", self.first_name)
            print("Last Name:", self.last_name)
            print("Gender:", self.gender)
            print("Age:", self.age)
            print("Country:", self.country)

    def greet_user(self):
        """
        Greeting the users
        """
        if self.first_name == "Arman" and self.last_name == "Cam":
            print("Hello Admin!\nWelcome to the AQT Server")
        else:
            print("Hello", self.first_name, "!\nWelcome to the AQT Server\n")

    def increment_login_attempts(self):
        '''
        Increment the login attempts one by one, each time users try to enter
        '''
        self.login_attempts += 1
        print("You have tried logging in", self.login_attempts, "times")

    def reset_login_attempts(self):  # method
        '''
        Resetting the logging attempts
        '''
        self.login_attempts = 0
        print("Login Attempt has set to ", self.login_attempts)class Admin(User):
    def __init__(self, first_name, last_name, gender, age, country, privileges=''):
        super().__init__(first_name, last_name, gender, age, country)
        self.privileges = privileges

    def show_privileges(self):
        """
        Showing the privileges of the admin
        """
        if self.first_name == "Arman" and self.last_name == "Cam":
            print(self.privileges)
        else:
            print("You have no privileges!")

    def add_privileges(self, new_privilege):
        """
        Adding a new privilege if needed
        """
        if self.first_name == "Arman" and self.last_name == "Cam":
            self.privileges += new_privilege
        else:
            print("You can not add any privilege!")user1 = User("Keane", "Cam", "Male", 20, "Canada")
user2 = Admin("Keane", "Cam", "Male", 23, "USA")

user1.greet_user()
user1.describe_user()

user2.greet_user()
user2.describe_user()
user2.add_privileges("Ban User")
user2.show_privileges()

I guess this is the best way to implement
 
  • #34
Arman777 said:
Let me use "child-class".

You don't need to make up a new term. The term "subclass" describes this.

Arman777 said:
I was trying to know that can you still use the attributes of the User() in Admin() without making Admin a child-class of user (i.e Admin(User)).

If the answer is "no". That is fine by me.

The answer is no. See my post #11 for a description of a better way to do what it looks like you are trying to do.
 
  • #35
Arman777 said:
I guess this is the best way to implement

You have the basic idea of how you would make Admin a subclass of User, but your implementation of this still has some issues:

(1) If every admin is described by an instance of the Admin class, then why are you checking the first and last name in the show_privileges method? If a user is not an admin, you won't use the Admin class to describe them.

(2) It makes no sense to have an instance of User and an instance of Admin for the same user, which is what your user1 and user2 code appears to be doing (unless the first name of user2 is a typo and should be "Arman"). Either a user is an admin or they aren't. If they are, you create an instance of Admin for them. If they aren't, you create an instance of User for them.

(3) If you want to be able to call show_privileges and add_privileges on any user, without having to know whether they are admins or not, then you need to have show_privileges and add_privileges methods in the User class, and then override them in the Admin class. Something like this:

Python:
# in class User:

    def show_privileges(self):
        print("You have no privileges!")

    def add_privileges(self, new_privilege):
        print("You can not add any privilege!")

# in class Admin(User):

    def show_privileges(self):
        print(self.privileges)

    def add_privileges(self, new_privilege):
        self.privileges += new_privilege

Then you would create the two instances like so:

Python:
user1 = User("Keane", "Cam", "Male", 20, "Canada")
user2 = Admin("Arman", "Cam", "Male", 23, "USA")

Note that it's up to the code creating the instances to decide whether to create an instance of the User class or the Admin class for each user.
 
  • Like
Likes pbuk
  • #36
PeterDonis said:
That's not what your code posted in the OP is doing. Your code posted in the OP is assigning a new instance of the Admin class to the admin instance attribute of each new instance of the User class. Since each new instance of the Admin class has exactly the same attributes, it's impossible to use that to distinguish between admin and non-admin users, so your code is not doing what you intend.

What it looks like you are trying to do is to distinguish admin users from other users by their names (i.e., users with particular names are admins, other users are not). The name is an attribute of the User class, so you don't need a separate Admin class to distinguish admin from non-admin users; you just need an attribute or property on each instance of the User class that says whether that user is an admin, based on their name (or whatever other criterion you want). One example of how to do this would be to add the following to your User class:

Python:
@property
def is_admin(self):
    return self.first_name == "Arman" and self.last_name == "Cam"

Then you can use this property in the show_privileges method of the User class, for example:

Python:
def show_privileges(self):
        """
        Showing the privileges of the admin
        """
        if self.is_admin:
            print(self.privileges)
        else:
            print("You have no privilege")

And for this to work, you would need to replace the line self.admin = Admin(privileges='') in the User class constructor with self.privileges = '' (or you could pass the privileges in as a parameter).
I did this, it also seems nice. I did not much pay attention at first because I wanted Admin and User to be separate classes. But this is also good.
 
  • #37
PeterDonis said:
(1) If every admin is described by an instance of the Admin class, then why are you checking the first and last name in the show_privileges method? If a user is not an admin, you won't use the Admin class to describe them.
That make sense
PeterDonis said:
(2) It makes no sense to have an instance of User and an instance of Admin for the same user, which is what your user1 and user2 code appears to be doing (unless the first name of user2 is a typo and should be "Arman"). Either a user is an admin or they aren't. If they are, you create an instance of Admin for them. If they aren't, you create an instance of User for them.
That was just to try things. I was playing with the code to see how it works.
PeterDonis said:
Note that it's up to the code creating the instances to decide whether to create an instance of the User class or the Admin class for each user.
Yes indeed. As I said in my first post. This is just my personal project for fun. I am just trying to understand creating classes, methods etc. and one can implement many things on the code, which solely depends on who is coding, or what the client/problem wants from the coder
 
  • #38
Python:
class User():
    def __init__(self, first_name, last_name, gender, age, country, admin_status):
        """
        Description of the user
        """
        self.first_name = first_name
        self.last_name = last_name
        self.gender = gender
        self.age = age
        self.country = country
        self.login_attempts = 0
        self.admin_status = admin_status
        self.privileges = ''

    def describe_user(self):
        """
        Printing the users information, if the user is admin do not give any information
        """
        if self.admin_status:
            print("This information is classified")
        else:
            print("First Name: ", self.first_name)
            print("Last Name:", self.last_name)
            print("Gender:", self.gender)
            print("Age:", self.age)
            print("Country:", self.country)

    def greet_user(self):
        """
        Greeting the users
        """
        if self.admin_status:
            print("Hello Admin!\nWelcome to the AQT Server")
        else:
            print("Hello", self.first_name, "!\nWelcome to the AQT Server\n")

    def show_privileges(self):
        if self.admin_status:
            print(self.privileges)
        else:
            print("You don't have any privileges")

    def add_privileges(self, new_privilege):
        if self.admin_status:
            self.privileges += new_privilege + "\n"
        else:
            print("You don't have any privileges")user1 = User("Keane", "Ferris", "Male", 20, "Canada", True)
user1.greet_user()
user1.describe_user()

user1.add_privileges("dream on")
user1.add_privileges("back")
user1.show_privileges()

I think this is much more better. I added

Python:
        self.admin_status = admin_status

So any user can be admin and any admin can be back to user, just by changing admin status.

It is similar to what @PeterDonis done in Post 11, however his code was working for only 1 person. If you wanted to create another admin, I had to define user and admin and their privileges one by one, which is really bad if you have for instance 100 user. By doing this its much easier.
 
  • #39
Arman777 said:
his code was working for only 1 person

Only because the definition you were using in your previous code allowed only one person, the person whose first name was "Arman" and whose last name was "Cam", to be an admin. Change the requirements and of course you change the code.
 
  • Like
Likes Vanadium 50 and Arman777
  • #40
PeterDonis said:
Only because the definition you were using in your previous code allowed only one person, the person whose first name was "Arman" and whose last name was "Cam", to be an admin. Change the requirements and of course you change the code.
Yes indeed :angel:
 
  • #41
Arman777 said:
By doing this its much easier.

That depends on the actual requirements of the actual system. What you are doing now assumes that any user can be an admin, and that users can shift back and forth at any time between being an admin and not being one. There may be some real-world systems where that is true, but for many it is not true.

Even your original definition, where only one particular user with one particular name can be an admin, might be the right one for some real-world systems. I actually coded an initial prototype of a system some years ago where I did exactly that: I hard-coded two names (mine and one other persons) as the only user names who could be admins. That meant I didn't have to worry about the details of managing who had admin rights, or whether they could change at any time, while I was working on other more important parts of the prototype.
 
  • Like
Likes Arman777
  • #42
That is also possible
 
  • #43
There are many different possibilities for dealing with this issue which is known as 'Authorization', and many popular Python frameworks have their own implementations: you could learn a lot about how and why we design classes like we do from looking at Flask and Django.
 
  • Like
Likes Arman777
  • #44
pbuk said:
There are many different possibilities for dealing with this issue which is known as 'Authorization', and many popular Python frameworks have their own implementations: you could learn a lot about how and why we design classes like we do from looking at Flask and Django.
Thanks. I am also open to any project ideas, that does not much require pygame or web server stuff.
 

Similar threads

  • · Replies 9 ·
Replies
9
Views
1K