วนรอบตัวแปรสมาชิกทั้งหมดของคลาสใน python


94

คุณจะได้รับรายการตัวแปรทั้งหมดในคลาสที่สามารถทำซ้ำได้อย่างไร เหมือนคนในท้องถิ่น () แต่สำหรับชั้นเรียน

class Example(object):
    bool143 = True
    bool2 = True
    blah = False
    foo = True
    foobar2000 = False

    def as_list(self)
       ret = []
       for field in XXX:
           if getattr(self, field):
               ret.append(field)
       return ",".join(ret)

สิ่งนี้ควรกลับมา

>>> e = Example()
>>> e.as_list()
bool143, bool2, foo

ทำไมใช้ใช้for field in [ self.bool143, self.bool2, self.blah, self.foo, self.foobar2000 ]ไม่ได้? เกิดขึ้นได้อย่างไรที่คุณไม่ทราบตัวแปรอินสแตนซ์ของคลาส
ล็อต

4
S.Lott: นั่นคือสิ่งที่ฉันทำยังไงก็ได้ ในโค้ดจริงของฉันฉันมีตัวแปรเหมือน 40 ตัวและฉันคิดว่ามันจะดีกว่าและแห้งกว่าที่จะไม่ต้องทำรายการซ้ำด้วยตนเอง
บาทหลวง

คำตอบ:


157
dir(obj)

ให้คุณสมบัติทั้งหมดของวัตถุแก่คุณ คุณต้องกรองสมาชิกออกจากวิธีการต่างๆด้วยตัวคุณเอง:

class Example(object):
    bool143 = True
    bool2 = True
    blah = False
    foo = True
    foobar2000 = False

example = Example()
members = [attr for attr in dir(example) if not callable(getattr(example, attr)) and not attr.startswith("__")]
print members   

จะให้คุณ:

['blah', 'bool143', 'bool2', 'foo', 'foobar2000']

9
ทำไมอินสแตนซ์วัตถุ: dir (ตัวอย่าง ()) แทนที่จะเป็นเพียงประเภทคลาส dir (ตัวอย่าง)
Erdal

9
และคุณได้รับค่าอย่างไร?
knutole

7
@knutole: getattr (object, attr)
opello

8
วิธีการcallable(attr)ทำงานหรือไม่ attrสตริงไม่ใช่เหรอ
cubuspl42

6
คุณควรใช้vars(Example).items()หรือvars(instance.__class__).items()แทนdir()ว่าคุณต้องการตรวจสอบว่าสามารถเรียกใช้ได้หรือไม่เพราะผบ. จะส่งกลับstringเป็นชื่อเท่านั้น ..
rrw

121

หากคุณต้องการเฉพาะตัวแปร (ไม่มีฟังก์ชัน) ให้ใช้:

vars(your_object)

5
คุณยังคงต้องกรองvarsแต่นี่คือคำตอบที่ถูกต้อง
พูดไม่ชัด

3
ชอบวิธีนี้มากที่จะใช้เพื่อค้นหาสิ่งที่จะทำให้เป็นอนุกรมก่อนที่จะส่งสถานะผ่านเครือข่ายเช่น ...
ธ ม

9
varsไม่ได้รวมตัวแปรระดับเพียงตัวแปรอินสแตนซ์
DilithiumMatrix

2
@DilithiumMatrix คุณต้องใช้ vars (THECLASSITSELF) ในคลาสเพื่อรับตัวแปรคลาส ตรวจสอบคำตอบของฉันด้านล่าง
AmirHossein

2
การใช้วิธีนี้เพื่อตอบคำถามของ OP โดยเฉพาะ: members = list(vars(example).keys())as (อย่างน้อยที่สุดใน python3) varsจะคืนค่าการdictแมปชื่อตัวแปรสมาชิกให้เป็นค่า
Michael Hall

28

@truppo: คำตอบของคุณเกือบจะถูกต้อง แต่ที่เรียกได้จะส่งกลับเท็จเสมอเนื่องจากคุณเพิ่งส่งสตริง คุณต้องการสิ่งต่อไปนี้:

[attr for attr in dir(obj()) if not callable(getattr(obj(),attr)) and not attr.startswith("__")]

ซึ่งจะกรองฟังก์ชันออกไป


6
>>> a = Example()
>>> dir(a)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__',
'__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', 'bool143', 'bool2', 'blah',
'foo', 'foobar2000', 'as_list']

อย่างที่คุณเห็นนั่นทำให้คุณมีคุณสมบัติทั้งหมดดังนั้นคุณจะต้องกรองข้อมูลออกเล็กน้อย แต่โดยพื้นฐานแล้วdir()คือสิ่งที่คุณกำลังมองหา


-1
row2dict = lambda r: {c.name: str(getattr(r, c.name)) for c in r.__table__.columns} if r else {}

ใช้สิ่งนี้


ทำให้เข้าใจผิด ไม่มีแอตทริบิวต์ " ตาราง " ในชั้นเรียนโดยค่าเริ่มต้น
ben26941

-2
    class Employee:
    '''
    This class creates class employee with three attributes 
    and one function or method
    '''

    def __init__(self, first, last, salary):
        self.first = first
        self.last = last
        self.salary = salary

    def fullname(self):
        fullname=self.first + ' ' + self.last
        return fullname

emp1 = Employee('Abhijeet', 'Pandey', 20000)
emp2 = Employee('John', 'Smith', 50000)

print('To get attributes of an instance', set(dir(emp1))-set(dir(Employee))) # you can now loop over

-3

วิธีง่ายๆในการทำเช่นนี้คือบันทึกอินสแตนซ์ทั้งหมดของคลาสในไฟล์list.

a = Example()
b = Example()
all_examples = [ a, b ]

วัตถุไม่ได้เกิดขึ้นเองตามธรรมชาติ บางส่วนของโปรแกรมของคุณสร้างขึ้นด้วยเหตุผล การสร้างทำด้วยเหตุผล การรวบรวมไว้ในรายการสามารถทำได้ด้วยเหตุผล

หากคุณใช้โรงงานคุณสามารถทำได้

class ExampleFactory( object ):
    def __init__( self ):
        self.all_examples= []
    def __call__( self, *args, **kw ):
        e = Example( *args, **kw )
        self.all_examples.append( e )
        return e
    def all( self ):
        return all_examples

makeExample= ExampleFactory()
a = makeExample()
b = makeExample()
for i in makeExample.all():
    print i

ฉันชอบแนวคิดนี้ (ฉันอาจจะใช้สิ่งนั้นในโครงการปัจจุบัน) ไม่ใช่คำตอบสำหรับคำถามแม้ว่า OP ต้องการแสดงรายการคุณลักษณะไม่ใช่อินสแตนซ์เอง
balpha

@balpha: อ๊ะ. ไม่ได้อ่านคำถาม. 90% ของเวลานี้ซ้ำกับ "ฉันจะค้นหาอินสแตนซ์ทั้งหมดของคลาสได้อย่างไร" คำถามจริง (ตอนนี้ที่คุณชี้ให้เห็น) ไม่สมเหตุสมผล คุณรู้จักตัวแปรอินสแตนซ์เพียงแค่สร้างรายการ
ล็อต
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.