【问题标题】:What are an 'object's attributes' in python and in general?python和一般情况下的“对象属性”是什么?
【发布时间】:2019-03-12 04:24:02
【问题描述】:

我正在学习 python,其中一个正在教授的内置函数是 dir()——该课程将其描述为 “返回对象的有效属性目录”,但是什么是对象的属性吗?

我想我在返回的属性列表中看到了一些成员函数,__len__ 我假设指的是len(),但是列出的所有这些其他内容是什么?

还有,它可能不完整是什么意思?

这是我的第一个问题,如果我没有花 45 分钟来解决这个问题,我不会问这个问题。

【问题讨论】:

  • 您可能需要查看this
  • 您可以将对象(又名实例)属性视为对象命名空间中存在的所有名称(也称为变量)。它们可以引用任何类型的对象,包括从类及其超类继承的方法和内容。

标签: python attributes directory


【解决方案1】:

您混淆了一些事情,并且可能对一些令人困惑的事情感到困惑。

__len__ 不是指len(),而是len(something) 会调用something__len__ 方法。任何具有__len__ 方法的对象都可以通过调用len(something) 来询问其长度。请注意这与something.len() 有何不同以及它比something.__len__() 更易读。

Python 中对象的属性包括您通常认为的它的属性,以及它的所有属性和方法名称。所以对于这个例子:

class T:
    def __init__(self):
        self.x = 10

    def afunc(self):
        return 20

    @property
    def y(self):
        return self.x

T 的任何实例都将在其属性中包含xafuncy。对象的属性还包括其基类的所有属性(即它继承自哪些类),最终总是包括object 的属性。

关于它不完整的评论是在引用没有__dir__ 属性的对象,该属性将由dir() 函数调用。在这些情况下,dir() 函数将查看其 __dict__ 属性(如果可用),因此它可能无法提供完整的属性列表 - 请注意,大多数对象并非如此。

【讨论】:

  • 感谢您的回答,所以,实际上,一个对象的属性是从其类继承的成员函数和变量,以及对象自己的方法和变量,对吧?
  • 是的,差不多就是这样。通常,将对象的“变量”称为“属性”,将对象的“函数”称为“方法”,这就是 Python 有点令人困惑的原因,因为对象的方法也出现在它们的属性列表中。
  • 我明白了,谢谢你的解释!而且据我了解,从对象类继承的函数也叫成员函数,对吧?
  • 我认为在谈到 C++ 时,“成员函数”这个词更常见,因为 C++ 实现 OOP 方法的方式。但是,如果您说的是一般的面向对象术语,则方法更为常见。当然,铁杆 C++ 开发人员可能会坚持认为“方法”是一种 Java 主义,但坦率地说,我认为像 Smalltalk 这样的早期语言值得称赞(他们通常使用“方法”)。然而,OO 标准作品“设计模式”使用“操作”,只是为了避免看起来的整个讨论——如果所有标准都不好,你只是发明一个新的,对吧?
【解决方案2】:

取决于您所谈论的对象类型。假设有问题的对象是一个类,那么类名称空间下的所有属性都由 dir 列出。这包括任何方法,用户特别声明的类级别变量+任何继承的东西。记住类继承自'object',它提供了一堆特殊的方法

看看下面的代码是否有意义:

class A(object):
    def __init__(self, a):
        self.a = a
    def m(self):
        print("in method")
    @property
    def p(self):
        print("in prop")
    def __get__(self, obj, owner):
        print("in get")
        return self
    def __call__(self, *args):
        print("call")

如果你对 A 类执行 dir,你将看到 A 命名空间下的所有属性 + 继承自对象的属性,如下所示。还可以尝试 dir(object) 来查看具体的“对象”属性是什么

['__call__',
 '__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__get__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'm',
 'p']

请注意,self.a 未列为 self.a 属于实例而不是类本身

要添加,您的对象编号是列表类型,因此列出了列表的所有属性(请参阅 dir(list))

【讨论】:

    【解决方案3】:

    这些是对象超类拥有的方法。任何继承自 this 的对象都会获得这些属性。现在我认为您对__len__()len(something) 感到困惑。

    len() 是一个默认引入作用域的函数。它所做的只是调用驻留在该对象中的__len__() 函数。

    假设您调用了len([1,2,3,4]),这将调用__len__() 类中存在的List 方法,即创建此列表对象的类。

    各种函数将这些dunder 方法用于自己的目的。

    这是一个例子

    class Test:
        def __myfunc__(self):
            return "I have been called"
    
    def testFunc(object):
        return object.__myfunc__()
    
    test = Test()
    
    testFunc(test)
    

    '我被召唤'

    其中许多功能也以同样的方式工作。

    【讨论】:

    • 有趣,所以这不是内置函数独有的东西,如果我创建另一个像这样的类class Test_2: def __myfunc__(self): return "I was called" 然后创建该类类型的对象test2 = Test_2() 然后,调用testFunc(test) 会仍然返回'我被调用',但是testFunc(test2) 相同的函数,不同的参数,会返回'我被调用' 是吗?
    【解决方案4】:

    假设你有一个班级Person

    class Person:
        name = "Samuel"
        age = 50
        country = "India"
    
        def method1(self):
            print("Method 1")
    
    print(dir(Person))
    

    上述程序的输出如下所示:

    ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
    '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
    '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__',
    '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', 
    '__str__', '__subclasshook__', '__weakref__', 
    'age', 'country', 'method1', 'name']
    

    您可以从上面的输出中看到它返回该对象的有效属性的排序列表。如果您查看类 Person

    姓名、年龄、国家 是属性,method1 是该类的方法。因此,当您使用 dir(Person) 时,它将显示该类的所有属性。

    默认的 dir() 机制对不同类型的对象表现不同,因为它试图生成最相关而不是完整的信息:

    • 如果对象是模块对象,则列表包含模块属性的名称。
    • 如果对象是类型或类对象,则列表包含其属性的名称,并递归地包含其基类的属性。
    • 否则,该列表包含对象的属性名称、其类属性的名称,以及其类的基类属性的递归名称。

    例如,

    a = [1,2,3,45]
    print(dir(a))
    

    这将打印:

    ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', 
     '__dir__', '__doc__', '__eq__', '__format__', '__ge__', 
     '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', 
     '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', 
     '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', 
     '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', 
     '__setattr__', '__setitem__', '__sizeof__', '__str__', 
     '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 
     'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
    

    在这里,您可以看到一些其他属性名称插入、弹出、删除等。如果您检查以前的列表,它们不存在。 这是因为不同类型的对象具有不同的属性,通过这些属性,您可以以不同的形式使用这些对象。 您可以使用a.pop(2) 删除元素等。

    len 我假设是指 len()

    通常,len() 是您用来获取对象长度的公共接口。 __len__ 方法是支持长度概念的对象期望实现的实现。 len() 致电__len__()

    我想我在返回的属性列表中看到了一些成员函数,len 我假设是指 len(),但是列出的所有这些其他内容是什么?

    访问以下链接,https://docs.python.org/3.6/reference/datamodel.html#object.dir。其中大部分都列在这里。还描述了其中的用法。

    【讨论】:

      猜你喜欢
      • 2010-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-30
      • 2020-12-18
      • 2010-12-04
      • 2017-02-01
      • 2015-07-14
      相关资源
      最近更新 更多