Better method to check all objects' parameters with a single call
Better method to check all objects' parameters with a single call
I want to get all objects which age is less than 18. How can easily do that?
Should I had to pass all objects to get_nonage to get it?
class People:
def __init__(self, uid, age):
self.uid = uid
self.age = age
def get_nonage(self):
# print nonage here which age<18
# expected output: {1: 11, 3: 15}
pass
p1 = People(1, 11)
p2 = People(2, 20)
p3 = People(3, 15)
...
People.get_nonage()
People.get_nonage()
get_nonage
Can I just know the class is People, then use some method of People to directly get all data of its objects without know how many objects I have, possible?
– Miss Bang
11 mins ago
Your design seems flawed here. Firstly,
People
is really Person
. This is an important distinction. Once you create a person, you'll put them into an array (list) called people
. Then, reducing/filtration/mapping operations are simple, in your case you're filtering on age: [p for p in people if p.age < 18]
– ggorlen
8 mins ago
People
Person
people
[p for p in people if p.age < 18]
Once you create a person, you'll put them into an array called people, what this mean?
– Miss Bang
7 mins ago
Where I add the array people?
– Miss Bang
7 mins ago
3 Answers
3
In order to search all of the People
objects, you have to have all of the People
objects.
People
People
But that implies you shouldn't have them in a bunch of separate variables in the first place, but in some collection, like a list.
Then, get_nonage
can take that list.
get_nonage
While we're at it, there's no reason for get_nonage
to be a method. It's not something that a People
instance does, it's something you do to a bunch of People
instances.
get_nonage
People
People
So:
class People:
# ...
def get_nonage(people):
nonage = {person.uid: person.age for person in people if person.age<18}
print(nonage)
people = [
People(1, 11),
People(2, 20),
People(3, 35)
]
get_nonage(people)
In a comment, you ask:
Can I just know the class is People, then use some method of People to directly get all data of its objects
What method would that be? You haven't written one. A class normally doesn't know all of its instances.
Of course if you really want it to, you can make a class record its instances in a class attribute. (A normal instance, like age
, has a separate value for each instance. A class attribute has a single value shared by all instances.)
age
For example:
class People:
all_people =
def __init__(self, uid, age):
self.uid = uid
self.age = age
self.all_people.append(self)
If you do that, then you can make get_nonage
into a class method—that is, a method meant to be called on the class itself, rather than on an instance. A class method gets the class, cls
, as its first parameter, instead of an instance, self
, and it can only access class attributes, like the all_people
we just created above.
get_nonage
cls
self
all_people
@classmethod
def get_nonage(cls):
nonage = {person.uid: person.age for person in cls.all_people if person.age<18}
print(nonage)
And now, you can call it, without having to pass it anything, because it already knows everything:
people = [
People(1, 11),
People(2, 20),
People(3, 35)
]
People.get_nonage()
However, this is usually not a great design. For example, what if you wanted to delete a person? Previously, you'd just remove them from the list (or, in your original version, reassign p3
to something else). But then People.all_people
won't know you did that; that person will still be there, and still be counted, even though you no longer have any way to access them.
p3
People.all_people
Try next:
class People:
def __init__(self, uid, age):
self.uid = uid
self.age = age
@classmethod
def get_nonage(cls, context):
print({obj.uid: obj.age for (obj_name, obj) in context.items() if type(obj) == cls and obj.age < 18})
p1 = People(1, 11)
p2 = People(2, 20)
p3 = People(3, 15)
People.get_nonage(globals())
Output:
{1: 11, 3: 15}
You can use global variable
non_age = {}
class People:
def __init__(self, uid, age):
self.uid = uid
self.age = age
if age < 18:
global non_age
non_age[uid] = age
if __name__ == '__main__':
p1 = People(1, 11)
p2 = People(2, 20)
p3 = People(3, 15)
print(non_age)
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
First,
get_nonage
should probably not be an instance method. Second, yes, you will have to pass it all of the People object if you want it to search all of the People objects. But that implies that you should be storing them in a list, instead of in a bunch of separate variables. Then you just pass the list.– abarnert
13 mins ago