15779327169 发表于 2024-4-17 22:55:59

类与对象相关问题

class Mylist(object):
    def __init__(self):
      self.items = []
    def add(self, val):
      self.items.append(val)
    def __iter__(self):
        retrun MyIerator()
classMyIerator(object)
    def __init__(self):
      pass
    def __next__(self):
        pass
    def __iter__(self):
        pass
list1 = Mylist()
list1.add(1)
list1.add(2)
print(list1.items)
有几个疑问:
1、class Mylist(object): 和class Mylist: 这两种写法有什么不同
2、   def add(self, val):
      self.items.append(val) ,这里是append(val)而不是append(self.val),这两种添加有什么不同。
3、    def __iter__(self):
        retrun MyIerator()这里调用 类MyIerator的对象为什么是MyIerator(),括号里面不需要加入self吗,为什么是空的

FishC 发表于 2024-4-17 22:56:17

1、class Mylist(object) 和 class Mylist: 这两种写法的不同在于是否显式地指定该类继承自`object`。在Python 2.x中,如果不显式指定,那么类将默认继承自`object`,即`class Mylist:`等同于`class Mylist(object):`。而在Python 3.x中,默认所有类都继承自`object`,所以二者是等效的。

2、`append(val)` 是向`self.items`列表追加元素`val`。`append(self.val)` 是向`self.items`列表追加实例变量`val`的值,而不是实例本身。在这个例子中,`self.items`是一个空列表,所以无法使用`self.val`来追加,因为`self.val`是不存在的。

3、在 `def __iter__(self): return MyIterator()` 代码中,`MyIterator()` 创建了一个新的`MyIterator`对象的实例,并返回给调用者。这里括号内为空,是因为`MyIterator`类的`__init__`方法里面没有参数。在创建对象实例时,`self`参数会被隐式传递给`__init__`方法,所以不需要显式传入`self`。

另外,你的代码中有一个拼写错误。`retrun` 应该是 `return`。同时,在`MyIterator`类中,还需要实现`__next__`和`__iter__`方法。下面是修正后的代码:

class MyList(object):
    def __init__(self):
      self.items = []

    def add(self, val):
      self.items.append(val)

    def __iter__(self):
      return MyIterator(self)

class MyIterator(object):
    def __init__(self, mylist):
      self.mylist = mylist
      self.current_index = 0

    def __next__(self):
      if self.current_index < len(self.mylist.items):
            value = self.mylist.items
            self.current_index += 1
            return value
      else:
            raise StopIteration

    def __iter__(self):
      return self

list1 = MyList()
list1.add(1)
list1.add(2)

for item in list1:
    print(item)

输出结果为:
1
2

这样就实现了一个可迭代的自定义列表类。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

isdkz 发表于 2024-4-17 23:18:36

1、class Mylist(object) 表示继承 object 类,而所有类都是默认继承 object 的,所以 class Mylist(object): 和class Mylist:并没有什么不同,建议写法:class Mylist:

2、append(val)和 append(self.val) 的区别,val 是 方法中传入的局部变量,而 self 是实例本身,所以 self.val 是实例的属性,而该实例并没有 val 属性,而且该方法旨在往自定义的列表对象中添加外部数据,所以应该用 val

3、self 参数是由解释器自动传入的,所以你自己只需要传入除 self 以外的参数即可,而 MyIerator 类的 __init__ 方法除了 self 之外没有别的参数,所以也就是说你自己不需要传入任何参数

15779327169 发表于 2024-4-18 09:10:57

isdkz 发表于 2024-4-17 23:18
1、class Mylist(object) 表示继承 object 类,而所有类都是默认继承 object 的,所以 class Mylist(object ...

感谢大神!第二点我还不是特别清楚,其他的两个问题我明白了,感谢!

15779327169 发表于 2024-4-18 09:13:32

FishC 发表于 2024-4-17 22:56
1、class Mylist(object) 和 class Mylist: 这两种写法的不同在于是否显式地指定该类继承自`object`。在Py ...

关于第二个问题的解答:
append(val)和 append(self.val) 的区别,val 是 方法中传入的局部变量,而 self 是实例本身,所以 self.val 是实例的属性,而该实例并没有 val 属性,而且该方法旨在往自定义的列表对象中添加外部数据,所以应该用 val。
是不是可以理解为def __init__(self): 初始化函数中没有val这个属性,所以不能添加self.val这个属性,对于第二个问题我还不是特别理解,请举个例子说明一下

FishC 发表于 2024-4-18 09:13:43

15779327169 发表于 2024-04-18 09:13
关于第二个问题的解答:
append(val)和 append(sel ...

你的理解基本上是正确的,`def __init__(self):` 初始化函数中没有 `val` 这个属性,所以不能直接使用 `self.val`。下面我来举一个例子来说明这个问题。

假设我们有一个自定义的列表类`MyList`,其中有一个实例变量`items`用于存储列表元素。现在我们定义一个方法`add(self, val)`,用于向列表中添加元素。例如:

class MyList(object):
    def __init__(self):
      self.items = []

    def add(self, val):
      self.items.append(val)

在这个例子中,`val` 是一个局部变量,是 `add` 方法的参数。当调用 `add` 方法时,我们传入一个具体的值,该值会被存储到 `self.items` 列表中。例如:

my_list = MyList()
my_list.add(1)
my_list.add(2)
print(my_list.items)# 输出结果为

在这个例子中,我们创建了一个 `MyList` 实例 `my_list`,然后连续调用了 `add` 方法两次,分别传入了 `1` 和 `2` 这两个值。`add` 方法内部通过 `self.items.append(val)` 将这些值添加到了 `self.items` 列表中。

如果我们修改 `add` 方法为 `add(self, self.val)`,并尝试使用 `my_list.add(1)` 来添加元素,将会引发错误,因为 `MyList` 实例并没有名为 `val` 的属性。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

isdkz 发表于 2024-4-18 09:34:14

15779327169 发表于 2024-4-18 09:13
关于第二个问题的解答:
append(val)和 append(self.val) 的区别,val 是 方法中传入的局部变量,而 s ...

对的,通常实例属性都是在 __init__ 方法中赋予的,而 __init__ 方法中并没有初始化 val 这个属性,而 MyList 类也并不具备 val 这个属性(因为当实例属性访问不到就会去访问类属性),所以用 self.val 是不正确的,

而我们需要的是往 MyList 对象的 item 属性中添加数据,这个数据是从外部传进来的,而不是它自身的,所以不应该用 self. ,自身具有的才需要用 self.

self.items.append(val) 中因为 items 是自身具有的,所以用 self.items,而 val 是从外部传进来的,不需要用 self.

15779327169 发表于 2024-4-18 09:47:45

isdkz 发表于 2024-4-18 09:34
对的,通常实例属性都是在 __init__ 方法中赋予的,而 __init__ 方法中并没有初始化 val 这个属性,而 My ...

豁然开朗!感谢
页: [1]
查看完整版本: 类与对象相关问题