รับแอตทริบิวต์ของคลาส


106

ฉันต้องการรับคุณลักษณะของคลาสให้พูดว่า:

class MyClass():
  a = "12"
  b = "34"

  def myfunc(self):
    return self.a

ใช้MyClass.__dict__ให้ฉันรายการคุณลักษณะและฟังก์ชั่นและฟังก์ชั่นแม้จะชอบและ__module__ __doc__ในขณะที่MyClass().__dict__ให้คำสั่งว่างเปล่าแก่ฉันเว้นแต่ฉันจะตั้งค่าแอตทริบิวต์ของอินสแตนซ์นั้นอย่างชัดเจน

ฉันแค่ต้องการแอตทริบิวต์ในตัวอย่างด้านบนคือ: aและb


คำตอบ:


123

ลองใช้โมดูลการตรวจสอบ getmembersและการทดสอบต่างๆน่าจะเป็นประโยชน์

แก้ไข:

ตัวอย่างเช่น,

class MyClass(object):
    a = '12'
    b = '34'
    def myfunc(self):
        return self.a

>>> import inspect
>>> inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
[('__class__', type),
 ('__dict__',
  <dictproxy {'__dict__': <attribute '__dict__' of 'MyClass' objects>,
   '__doc__': None,
   '__module__': '__main__',
   '__weakref__': <attribute '__weakref__' of 'MyClass' objects>,
   'a': '34',
   'b': '12',
   'myfunc': <function __main__.myfunc>}>),
 ('__doc__', None),
 ('__module__', '__main__'),
 ('__weakref__', <attribute '__weakref__' of 'MyClass' objects>),
 ('a', '34'),
 ('b', '12')]

ตอนนี้วิธีการและคุณลักษณะพิเศษได้รับความสนใจของฉันซึ่งสามารถจัดการได้หลายวิธีวิธีที่ง่ายที่สุดคือการกรองตามชื่อ

>>> attributes = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
>>> [a for a in attributes if not(a[0].startswith('__') and a[0].endswith('__'))]
[('a', '34'), ('b', '12')]

... และยิ่งซับซ้อนมากขึ้นซึ่งอาจรวมถึงการตรวจสอบชื่อแอตทริบิวต์พิเศษหรือแม้แต่ metaclasses;)


ใช่มันเยี่ยมมาก! ฉันใช้สิ่งนี้: attributes = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a))) print [a[0] for a in attributes if '_' not in a[0]]
Mohamed Khamis

2
ระวัง - นั่นจะไม่รวมคุณสมบัติlike_this! นอกจากนี้ยังจะหลีกเลี่ยงแอตทริบิวต์ "ส่วนตัว" ซึ่งคุณอาจทำตามวัตถุประสงค์
Matt Luongo

สวัสดีครับผมรักที่มากเกินไปกับการชี้แจงเล็กน้อยในการแสดงออกinspect.getmembers(MyClass, ..., MyClassสามารถถูกแทนที่ด้วยชั้นเรียนหรือวัตถุและถ้าคุณต้องการรายการค่าของวัตถุของคุณคุณต้องแทนMyClassโดยตัวแปรวัตถุของคุณ (หรือselfถ้าคุณใส่ นิพจน์นี้ในdef __repr__()วิธีการเช่นฉัน)
herve-guerin

ฉันใช้สิ่งนี้ (ใน Python3) เพื่อรับฟังก์ชั่นที่ค้นหาค่า ' dict ' i = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a))); z = [_[1] for _ in i if _[0] in '__dict__'][0]จากนั้นมันก็เป็นเพียงเรื่องของการรับคีย์จาก z
double0darbo

43
def props(cls):   
  return [i for i in cls.__dict__.keys() if i[:1] != '_']

properties = props(MyClass)

7
ซึ่งจะรวมถึงชื่อเมธอด
lenhhoxung

10
ไม่ชัดเจนในการตรวจสอบif not i.startswith('_')มากกว่านี้: แทนที่จะเป็นif i[:1] != '_'?
Mikaelblomkvistsson

2
หมายเหตุ: ถ้าเราพูดถึงคลาสย่อย (สืบทอด) .__dict__.keys()จะไม่รวมคุณสมบัติจากพาเรนต์
vishes_shell

21

myfunc เป็นMyClassคุณลักษณะของ นั่นคือสิ่งที่พบเมื่อคุณเรียกใช้:

myinstance = MyClass()
myinstance.myfunc()

มันมองหาแอตทริบิวต์ที่ระบุmyinstanceชื่อmyfuncไม่พบเห็นว่าmyinstanceเป็นตัวอย่างMyClassและค้นหาที่นั่น

ดังนั้นสมบูรณ์รายการแอตทริบิวต์สำหรับMyClassมี:

>>> dir(MyClass)
['__doc__', '__module__', 'a', 'b', 'myfunc']

(โปรดทราบว่าฉันใช้ dir เป็นวิธีที่ง่ายและรวดเร็วในการลงรายชื่อสมาชิกของชั้นเรียน: ควรใช้ในรูปแบบการสำรวจเท่านั้นไม่ใช่ในรหัสการผลิต)

ถ้าคุณต้องการเฉพาะคุณลักษณะเฉพาะคุณจะต้องกรองรายการนี้โดยใช้เกณฑ์บางอย่างเพราะ__doc__, __module__และmyfuncไม่ได้พิเศษในทางใด ๆ ที่พวกเขาอยู่ในคุณลักษณะตรงเช่นเดียวกับที่aและbมี

ฉันไม่เคยใช้โมดูลการตรวจสอบที่ Matt และ Borealid อ้างถึง แต่จากลิงค์สั้น ๆ ดูเหมือนว่าจะมีการทดสอบเพื่อช่วยคุณทำสิ่งนี้ แต่คุณจะต้องเขียนฟังก์ชันเพรดิเคตของคุณเองเนื่องจากดูเหมือนว่าคุณต้องการ เป็นแอตทริบิวต์คร่าวๆที่ไม่ผ่านการisroutineทดสอบและไม่ขึ้นต้นและลงท้ายด้วยเครื่องหมายขีดล่างสองตัว

โปรดทราบ: เมื่อใช้class MyClass():ใน Python 2.7 คุณกำลังใช้คลาสแบบเก่าที่ล้าสมัยอย่างมาก class MyClass(object):ถ้าคุณกำลังทำเพื่อจงใจเข้ากันได้กับห้องสมุดเก่ามากคุณควรจะแทนการกำหนดระดับของคุณเป็น ใน Python 3 ไม่มีคลาส "แบบเก่า" และพฤติกรรมนี้เป็นค่าเริ่มต้น อย่างไรก็ตามการใช้คลาส newstyle จะทำให้คุณได้รับคุณสมบัติที่กำหนดโดยอัตโนมัติมากขึ้น:

>>> class MyClass(object):
        a = "12"
        b = "34"
        def myfunc(self):
            return self.a
>>> dir(MyClass)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b', 'myfunc']

6
ไม่มีใครขึ้นอยู่กับdir(): " เนื่องจาก dir () จัดทำขึ้นเพื่อความสะดวกในการใช้งานที่พรอมต์แบบโต้ตอบเป็นหลักจึงพยายามจัดหาชุดชื่อที่น่าสนใจมากกว่าที่จะพยายามจัดหาชุดชื่อที่กำหนดอย่างเข้มงวดหรือสม่ำเสมอและรายละเอียด อาจมีการเปลี่ยนแปลงพฤติกรรมการข้ามรุ่น . "(ดูเอกสารประกอบdir() )
Tadeck

@Tadeck: จุดดี ฉันใช้มันเพื่อเป็นตัวอย่างมากกว่าที่จะแนะนำเป็นวิธีแก้ปัญหาเนื่องจากมันไม่อนุญาตให้คุณกรองแอตทริบิวต์ตามสิ่งที่อ้างถึงได้อย่างง่ายดาย แต่ฉันควรจะอธิบายให้ชัดเจนมากกว่านี้
เบ็

16

การรับเฉพาะแอตทริบิวต์อินสแตนซ์เป็นเรื่องง่าย
แต่การรับแอตทริบิวต์คลาสโดยไม่มีฟังก์ชันนั้นค่อนข้างยุ่งยากกว่าเล็กน้อย

แอตทริบิวต์อินสแตนซ์เท่านั้น

หากคุณมีเพียงไปยังรายการเช่นคุณลักษณะการใช้งานเพียงแค่ .
for attribute, value in my_instance__dict__items()

>>> from __future__ import (absolute_import, division, print_function)
>>> class MyClass(object):
...   def __init__(self):
...     self.a = 2
...     self.b = 3
...   def print_instance_attributes(self):
...     for attribute, value in self.__dict__.items():
...       print(attribute, '=', value)
...
>>> my_instance = MyClass()
>>> my_instance.print_instance_attributes()
a = 2
b = 3
>>> for attribute, value in my_instance.__dict__.items():
...   print(attribute, '=', value)
...
a = 2
b = 3

อินสแตนซ์และคลาสแอตทริบิวต์

ที่จะได้รับนอกจากนี้ยังมีคุณลักษณะระดับโดยไม่ต้องฟังก์ชั่น, callable()เคล็ดลับคือการใช้

แต่วิธีการคงเป็นไปไม่ได้เสมอcallable !

ดังนั้นแทนที่จะใช้callable(value)use
callable( getattr(MyClass, attribute))

ตัวอย่าง

from __future__ import (absolute_import, division, print_function)

class MyClass(object):
   a = "12"
   b = "34"               # class attributes

   def __init__(self, c, d):
     self.c = c
     self.d = d           # instance attributes

   @staticmethod
   def mystatic():        # static method
       return MyClass.b

   def myfunc(self):      # non-static method
     return self.a

   def print_instance_attributes(self):
     print('[instance attributes]')
     for attribute, value in self.__dict__.items():
        print(attribute, '=', value)

   def print_class_attributes(self):
     print('[class attributes]')
     for attribute in self.__dict__.keys():
       if attribute[:2] != '__':
         value = getattr(self, attribute)
         if not callable(value):
           print(attribute, '=', value)

v = MyClass(4,2)
v.print_class_attributes()
v.print_instance_attributes()

หมายเหตุ: print_class_attributes()ควรเป็น       แต่ไม่ใช่ในตัวอย่างที่งี่เง่าและเรียบง่ายนี้@staticmethod

ผลลัพธ์สำหรับ

$ python2 ./print_attributes.py
[class attributes]
a = 12
b = 34
[instance attributes]
c = 4
d = 2

ผลลัพธ์เดียวกันสำหรับ

$ python3 ./print_attributes.py
[class attributes]
b = 34
a = 12
[instance attributes]
c = 4
d = 2

8

MyClass().__class__.__dict__

แต่ "สิทธิ" ที่จะทำเช่นนี้คือผ่านโมดูลตรวจสอบ


6
MyClass().__class__.__dict__==MyClass.__dict__
จามรี

5
ความคิดเห็นของ @ yak ไม่เป็นความจริง ดูสิ่งต่อไปนี้เกี่ยวกับความแตกต่างระหว่างแอตทริบิวต์คลาสและอินสแตนซ์ ดูstackoverflow.com/questions/35805/...
sholsapp

@sholsapp จริง ๆ แล้ว @yak พูดถูก ลิงก์ที่คุณให้บอกว่าMyClass().__class__.__dict__ != MyClass().__dict__แต่จามรีไม่ได้รวมทั้งวงเล็บด้านขวามือในกรณีของการที่ S / เขาเป็นที่ถูกต้อง
Shadi

2
import re

class MyClass:
    a = "12"
    b = "34"

    def myfunc(self):
        return self.a

attributes = [a for a, v in MyClass.__dict__.items()
              if not re.match('<function.*?>', str(v))
              and not (a.startswith('__') and a.endswith('__'))]

สำหรับอินสแตนซ์ของ MyClass เช่น

mc = MyClass()

ใช้type(mc)แทนMyClassความเข้าใจในรายการ อย่างไรก็ตามหากมีการเพิ่มแอตทริบิวต์แบบไดนามิกmcเช่นmc.c = "42"แอตทริบิวต์จะไม่แสดงเมื่อใช้type(mc)ในกลยุทธ์นี้ ให้เฉพาะแอตทริบิวต์ของคลาสดั้งเดิม

ที่จะได้รับพจนานุกรมที่สมบูรณ์แบบสำหรับเช่นชั้นคุณจะต้องรวมพจนานุกรมของและtype(mc).__dict__mc.__dict__

mc = MyClass()
mc.c = "42"

# Python 3.5
combined_dict = {**type(mc).__dict__, **mc.__dict__}

# Or Python < 3.5
def dict_union(d1, d2):
    z = d1.copy()
    z.update(d2)
    return z

combined_dict = dict_union(type(mc).__dict__, mc.__dict__)

attributes = [a for a, v in combined_dict.items()
              if not re.match('<function.*?>', str(v))
              and not (a.startswith('__') and a.endswith('__'))]

โซลูชันที่เรียบร้อยจริงๆ
Gitnik

2

ฉันไม่รู้ว่าตอนนี้มีการสร้างสิ่งที่คล้ายกันหรือไม่ แต่ฉันสร้างฟังก์ชันค้นหาแอตทริบิวต์ที่ดีโดยใช้ vars () vars () สร้างพจนานุกรมของคุณลักษณะของคลาสที่คุณส่งผ่าน

class Player():
    def __init__(self):
        self.name = 'Bob'
        self.age = 36
        self.gender = 'Male'

s = vars(Player())
#From this point if you want to print all the attributes, just do print(s)

#If the class has a lot of attributes and you want to be able to pick 1 to see
#run this function
def play():
    ask = input("What Attribute?>: ")
    for key, value in s.items():
        if key == ask:
            print("self.{} = {}".format(key, value))
            break
    else:
        print("Couldn't find an attribute for self.{}".format(ask))

ฉันกำลังพัฒนา Text Adventure ขนาดใหญ่ใน Python คลาส Player ของฉันจนถึงตอนนี้มีคุณสมบัติมากกว่า 100 รายการ ฉันใช้สิ่งนี้เพื่อค้นหาคุณลักษณะเฉพาะที่ฉันต้องการดู


ขออภัย vars () จะไม่ส่งคืนแอตทริบิวต์คลาส
user2682863

คุณได้ลองรันโค้ดที่ฉันโพสต์แล้วหรือยัง? Vars สามารถส่งคืนแอตทริบิวต์คลาสได้อย่างแน่นอน แสดงตัวอย่างว่าไม่เป็นอย่างไร? บางทีรหัสของฉันอาจไม่ถูกต้อง แต่การกำหนด vars () ให้กับตัวแปรและการใช้คีย์การค้นหาค่าผ่านตัวแปรนั้นสามารถส่งคืนแอตทริบิวต์คลาสได้
Corey Bailey

ชั้น T: x = 1; เสื้อ = T (); vars (t)
user2682863

คุณจะต้องรอจนกว่าฉันจะเลิกงานเพื่อแสดงให้คุณเห็นอย่างถูกต้อง แต่รหัสของคุณไม่ถูกต้อง คลาสอ็อบเจ็กต์ของคุณต้องกำหนด __init __ (self) และ x ต้องเป็น self.x = 1 จากนั้นกำหนด t = T () และใช้การพิมพ์ (vars (t)) จากนั้นจะแสดงพจนานุกรมของแอตทริบิวต์คลาสทั้งหมด
Corey Bailey

ไม่มีผู้ที่มีคุณลักษณะเช่นไม่แอตทริบิวต์คลาสย่อยหลายชั้นเรียนไม่เคยเรียกinit อย่างที่ฉันพูดไป vars () จะไม่ส่งคืนแอตทริบิวต์คลาสคุณต้องใช้ dir () หรือ checks.getmembers ()
user2682863

2

สิ่งนี้สามารถทำได้โดยไม่ต้องตรวจสอบฉันเดา

เข้าชั้นเรียนต่อไปนี้:

 class Test:
   a = 1
   b = 2

   def __init__(self):
     self.c = 42

   @staticmethod
   def toto():
     return "toto"

   def test(self):
     return "test"

ดูสมาชิกพร้อมกับประเภทของพวกเขา:

t = Test()
l = [ (x, eval('type(x.%s).__name__' % x)) for x in dir(a) ]

... ให้:

[('__doc__', 'NoneType'),
 ('__init__', 'instancemethod'),
 ('__module__', 'str'),
 ('a', 'int'),
 ('b', 'int'),
 ('c', 'int'),
 ('test', 'instancemethod'),
 ('toto', 'function')]

ดังนั้นในการส่งออกเฉพาะตัวแปรคุณต้องกรองผลลัพธ์ตามประเภทและชื่อไม่ได้ขึ้นต้นด้วย '__' เช่น

filter(lambda x: x[1] not in ['instancemethod', 'function'] and not x[0].startswith('__'), l)

[('a', 'int'), ('b', 'int'), ('c', 'int')] # actual result

แค่นั้นแหละ.

หมายเหตุ:หากคุณใช้ Python 3 ให้แปลงตัววนซ้ำเป็นรายการ

หากคุณต้องการเป็นวิธีที่มีประสิทธิภาพมากขึ้นที่จะทำมันใช้ตรวจสอบ


2

Python 2 & 3 ไม่นำเข้าโดยไม่ต้องนำเข้ากรองวัตถุตามที่อยู่

แนวทางแก้ไขโดยย่อ:

ส่งคืนdict {attribute_name: attribute_value}อ็อบเจ็กต์ที่กรอง กล่าวคือ{'a': 1, 'b': (2, 2), 'c': [3, 3]}

{k: val for k, val in self.__dict__.items() if not str(hex(id(val))) in str(val)}

ส่งคืนรายการ [attribute_names]วัตถุที่กรอง กล่าวคือ['a', 'b', 'c', 'd']

[k for k, val in self.__dict__.items() if not str(hex(id(val))) in str(val)]

ส่งคืนรายการ [attribute_values]วัตถุที่กรอง กล่าวคือ[1, (2, 2), [3, 3], {4: 4}]

[val for k, val in self.__dict__.items() if not str(hex(id(val))) in str(val)]

ไม่กรองวัตถุ

การลบifเงื่อนไข กลับ{'a': 1, 'c': [3, 3], 'b': (2, 2), 'e': <function <lambda> at 0x7fc8a870fd70>, 'd': {4: 4}, 'f': <object object at 0x7fc8abe130e0>}

{k: val for k, val in self.__dict__.items()}

วิธีแก้ปัญหาในระยะยาว

ตราบใดที่เริ่มต้นใช้งาน__repr__ไม่ได้แทนที่ifคำสั่งจะกลับมาTrueในกรณีที่แสดงเลขฐานสิบหกของสถานที่ในหน่วยความจำvalที่อยู่ใน__repr__สตริงผลตอบแทน

เกี่ยวกับการเริ่มต้นใช้งานของ__repr__คุณอาจจะพบว่ามีประโยชน์คำตอบนี้ ในระยะสั้น:

def __repr__(self):
    return '<{0}.{1} object at {2}>'.format(
      self.__module__, type(self).__name__, hex(id(self)))

Wich ส่งคืนสตริงเช่น:

<__main__.Bar object at 0x7f3373be5998>

ตำแหน่งในหน่วยความจำของแต่ละองค์ประกอบได้มาจากid()วิธีการ

Python Docsพูดเกี่ยวกับ id ():

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

รายละเอียดการใช้งาน CPython: นี่คือที่อยู่ของวัตถุในหน่วยความจำ


ลองด้วยตัวเอง

class Bar:

    def __init__(self):

        self.a = 1
        self.b = (2, 2)
        self.c = [3, 3]
        self.d = {4: 4}
        self.e = lambda: "5"
        self.f = object()

    #__str__ or __repr__ as you prefer
    def __str__(self):
        return "{}".format(

            # Solution in Short Number 1
            {k: val for k, val in self.__dict__.items() if not str(hex(id(val))) in str(val)}

        )

# Main
print(Bar())

เอาท์พุต:

{'a': 1, 'c': [3, 3], 'b': (2, 2), 'd': {4: 4}}

หมายเหตุ :

  • ทดสอบกับ Python 2.7.13และ Python3.5.3

  • ใน Python 2.x .iteritems()เป็นที่ต้องการมากกว่า.items()


1

เมื่อเร็ว ๆ นี้ฉันต้องคิดอะไรบางอย่างที่คล้ายกับคำถามนี้ดังนั้นฉันจึงต้องการโพสต์ข้อมูลพื้นฐานบางอย่างที่อาจเป็นประโยชน์สำหรับคนอื่น ๆ ที่ต้องเผชิญเช่นเดียวกันในอนาคต

นี่คือวิธีการทำงานใน Python (จากhttps://docs.python.org/3.5/reference/datamodel.html#the-standard-type-hierarchy ):

MyClassเป็นคลาสอ็อบเจ็กต์MyClass()เป็นอินสแตนซ์ของคลาสอ็อบเจ็กต์ อินสแตนซ์__dict__ถือเพียงแอตทริบิวต์และวิธีการเฉพาะสำหรับอินสแตนซ์นั้น (เช่นself.somethings) __dict__หากแอตทริบิวต์หรือวิธีการเป็นส่วนหนึ่งของการเรียนก็เป็นในชั้นเรียน เมื่อคุณทำMyClass().__dict__อินสแตนซ์ของMyClassจะถูกสร้างขึ้นโดยไม่มีแอตทริบิวต์หรือเมธอดนอกเหนือจากแอตทริบิวต์คลาสดังนั้นจึงว่างเปล่า__dict__

ดังนั้นถ้าคุณบอกว่าprint(MyClass().b), Python ตรวจสอบก่อน Dict อินสแตนซ์ใหม่และล้มเหลวในการค้นหาMyClass().__dict__['b'] bจากนั้นตรวจสอบระดับและพบMyClass.__dict__['b']b

นั่นเป็นเหตุผลที่คุณต้องมีinspectโมดูลเพื่อเลียนแบบกระบวนการค้นหาเดียวกันนั้น


2
สก็อต - ความคิดเห็นที่โพสต์เป็นคำตอบจะต้องถูกลบไม่เช่นนั้นเราจะจมอยู่ในนั้น แต่คำตอบบางส่วนหรือ "ดุนเป็นประโยชน์" ทางแก้ปัญหาคือยังคงคำตอบ คุณจะเห็นว่าฉันเปลี่ยนโพสต์ของคุณอย่างไร หวังว่าฉันจะคงเจตนาของคุณไว้ หากไม่เป็นเช่นนั้นคุณสามารถแก้ไขเพิ่มเติมให้เป็นรูปร่างได้ ไชโย!
Mogsdad

1

คุณสามารถใช้dir()ในการทำความเข้าใจรายการเพื่อรับชื่อแอตทริบิวต์:

names = [p for p in dir(myobj) if not p.startswith('_')]

ใช้getattr()เพื่อรับแอตทริบิวต์:

attrs = [getattr(myobj, p) for p in dir(myobj) if not p.startswith('_')]

1

วิธีแก้ปัญหาของฉันในการรับแอตทริบิวต์ทั้งหมด (ไม่ใช่วิธีการ) ของคลาส (ถ้าคลาสนั้นมี docstring ที่เขียนอย่างถูกต้องซึ่งมีแอตทริบิวต์ที่สะกดไว้อย่างชัดเจน):

def get_class_attrs(cls):
    return re.findall(r'\w+(?=[,\)])', cls.__dict__['__doc__'])

ชิ้นนี้cls.__dict__['__doc__']แยก docstring ของคลาส


1

ทำไมคุณต้องแสดงรายการคุณลักษณะ? ดูเหมือนว่าความหมายชั้นเรียนของคุณคือคอลเล็กชัน ในกรณีนี้ฉันแนะนำให้ใช้ enum:

import enum

class myClass(enum.Enum):
     a = "12"
     b = "34"

ระบุคุณสมบัติของคุณ? ไม่มีอะไรง่ายไปกว่านี้:

for attr in myClass:
    print("Name / Value:", attr.name, attr.value)

1

หากคุณต้องการ "รับ" แอตทริบิวต์มีคำตอบที่ง่ายมากซึ่งควรจะชัดเจน: getattr

class MyClass(object):
a = '12'
b = '34'
def myfunc(self):
    return self.a

>>> getattr(MyClass, 'a')
'12'

>>> getattr(MyClass, 'myfunc')
<function MyClass.myfunc at 0x10de45378>

ใช้งานได้ดีทั้งใน Python 2.7 และ Python 3.x

หากคุณต้องการรายชื่อของรายการเหล่านี้คุณจะยังคงต้องใช้การตรวจสอบ


1
คำตอบนั้นเรียบง่ายและถูกต้องเกินไปที่จะได้รับคะแนนหรือไม่และควรได้รับคะแนนที่ไม่ดีหรือไม่? ดูเหมือนว่าความประหยัดและความเรียบง่ายจะไม่คุ้มค่าอีกต่อไปในปัจจุบัน
fralau

0

สองฟังก์ชั่น:

def get_class_attr(Cls) -> []:
    import re
    return [a for a, v in Cls.__dict__.items()
              if not re.match('<function.*?>', str(v))
              and not (a.startswith('__') and a.endswith('__'))]

def get_class_attr_val(cls):
    attr = get_class_attr(type(cls))
    attr_dict = {}
    for a in attr:
        attr_dict[a] = getattr(cls, a)
    return attr_dict

ใช้:

>>> class MyClass:
    a = "12"
    b = "34"
    def myfunc(self):
        return self.a

>>> m = MyClass()
>>> get_class_attr_val(m)
{'a': '12', 'b': '34'}

0

สิ่งต่อไปนี้คือสิ่งที่ฉันต้องการ

ข้อมูลการทดสอบ

class Base:
    b = 'b'


class MyClass(Base):
    a = '12'

    def __init__(self, name):
        self.name = name

    @classmethod
    def c(cls):
        ...

    @property
    def p(self):
        return self.a

    def my_fun(self):
        return self.name
print([name for name, val in inspect.getmembers(MyClass) if not name.startswith('_') and not callable(val)])  # need `import inspect`
print([_ for _ in dir(MyClass) if not _.startswith('_') and not callable(getattr(MyClass, _))])
# both are equ: ['a', 'b', 'p']

my_instance = MyClass('c')
print([_ for _ in dir(my_instance) if not _.startswith('_') and not callable(getattr(my_instance, _))])
# ['a', 'b', 'name', 'p']

-2

ฉันรู้ว่านี่เป็นเวลาสามปีที่แล้ว แต่สำหรับคนที่จะเกิดคำถามนี้ในอนาคตสำหรับฉัน:

class_name.attribute 

ใช้งานได้ดี


3
ยกเว้นเมื่อคุณได้รับ AttributeError
rady

คุณมักไม่รู้ว่าอะไรattributeอยู่ตรงหน้า
Matt Luongo

-3

คุณสามารถใช้MyClass.__attrs__. มันให้แอตทริบิวต์ทั้งหมดของคลาสนั้น ไม่มีอะไรมาก


AttributeError: พิมพ์ object 'X' ไม่มีแอตทริบิวต์ ' attrs '
Ramazan Polat
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.