鱼C论坛

 找回密码
 立即注册
查看: 199|回复: 14

[已解决]为什么不能用函数形式person.shilifangfa()

[复制链接]
发表于 2024-4-19 13:26:12 From FishC Mobile | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
为什么不能用函数形式person.shilifangfa(p),这样写类属性age就提示没有这个swlf.age属性
最佳答案
2024-4-20 21:59:58
lc88824 发表于 2024-4-20 20:00
也就是说及时把13换成符合的P字母也还会报错是吧?只能是先用括号的参数 在上边引用一下 p=person()
...

对呀,总的来说得是 Person 的实例才应该传给 Person 的实例化方法的 self

加个括号就是实例化,比如 p = Person() 就是把 Person 实例化并赋给 p
IMG_1179.jpeg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-4-19 13:26:26 | 显示全部楼层
在Python中,我们可以通过两种方式来调用类的方法:

1. 使用实例对象调用方法:person.shilifangfa()。
2. 使用类名调用方法:Person.shilifangfa()。

如果你尝试使用实例对象调用方法(person.shilifangfa(p)),会出现属性错误提示说没有self.age属性。这是因为在使用实例对象调用方法时,self参数会自动传递给方法,实际上相当于person.shilifangfa(p, self),其中self代表了实例对象本身。

而在你的情况下,你使用了实例对象person调用方法person.shilifangfa(p),这样就会导致p参数直接传递给了self,相当于person.shilifangfa(person),并且将实例对象person作为self参数传入方法中。所以,在方法内部访问self.age时,会提示没有self.age属性。

所以,正确的调用方式是使用实例对象调用方法,不需要显式地传递任何参数:person.shilifangfa()。通过使用self关键字,方法内部可以正确地访问和操作实例对象的属性。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-19 13:32:03 | 显示全部楼层
实例方法只有在实例调用的时候才会自动帮你传入实例本身作为 self 参数,如果类调用实例方法则需要自己传入实例:
class Person:
    age = 0
    def shilifangfa(self):
        print(self)
        print(self.age)
        print(self.num)

p = Person()
p.num = 10

Person.shilifangfa(p)           # 需要自己传入实例 p
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-4-19 13:33:59 From FishC Mobile | 显示全部楼层
FishC 发表于 2024-4-19 13:26
在Python中,我们可以通过两种方式来调用类的方法:

1. 使用实例对象调用方法:person.shilifangfa()。
...

能否举例详细区分一下,为什么用函数传参方式使用
实例方法中不能间接调用类属性
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-19 13:34:18 | 显示全部楼层
lc88824 发表于 2024-04-19 13:33
能否举例详细区分一下,为什么用函数传参方式使用
实 ...


当我们在类中定义方法时,通常会使用self参数来表示实例对象本身。通过self参数,我们可以访问和操作实例对象的属性。在方法内部,可以使用self.attribute的方式来访问类的属性。

下面我们来演示一下为什么使用函数传参方式调用实例方法时不能间接访问类属性:
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def shilifangfa(self, p):
        print(f"传入的参数是:{p}")

        # 通过self访问类属性
        print(f"类属性age的值是:{self.age}")

现在我们创建一个Person对象,并尝试用函数传参方式调用实例方法:
p = Person("小明", 18)

person.shilifangfa(p)

这样调用会报错,提示没有age属性,原因是我们在调用方法时,将实例对象p作为参数传递给了方法。在方法内部,p会被赋值给self,所以`shilifangfa(self, p)`相当于`shilifangfa(p, p)`。这样,self就指向了p对象,而p对象没有age属性,因此会报错。

正确的方法调用方式是直接使用实例对象调用方法,不需要显式地传递任何参数:
p.shilifangfa()

这样就能够正确访问和操作实例对象中的类属性。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-19 13:46:23 | 显示全部楼层
本帖最后由 jackz007 于 2024-4-19 13:58 编辑
class Person :
    def shilifangfa(self) :
        print(self)
        print(self . age)
        print(self . num)
p = Person()
p . num = 10
p . shilifangfa()      # Python 不允许访问没有赋值的属性,p . age 在这个时候还没有赋值,在 shilifangfa() 中会进行访问,出错是必然
        直接调用类方法和访问类属性,试试这个代码
class Person :
    age = 18
    num = 66
    @classmethod
    def shilifangfa(cls) :
        print(cls . age)
        print(cls . num)

Person . shilifangfa()
p = Person()
p . shilifangfa()
print(Person . age)
print(Person . num)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-19 13:58:31 | 显示全部楼层
lc88824 发表于 2024-4-19 13:33
能否举例详细区分一下,为什么用函数传参方式使用
实例方法中不能间接调用类属性

我这么跟你说吧,所谓方法就是将函数与对象绑定,而方法在调用的时候会将它所绑定的对象作为第一个参数传入

给张图给你理解,不能理解的地方再提出来:
Snipaste_2024-04-19_13-57-39.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-4-20 07:36:55 From FishC Mobile | 显示全部楼层
isdkz 发表于 2024-4-19 13:58
我这么跟你说吧,所谓方法就是将函数与对象绑定,而方法在调用的时候会将它所绑定的对象作为第一个参数传 ...

如果举的例子中加个类属性age=10,在intm里面再加一个print(self.age)
把下面t=text()注释掉,直接用函数传参形式调用text.intm(P),这里就报错。我理解的是text.intm用函数传参定义了一个p的实例对象,按理来说可以继承类中age属性打印出self.age结果10的,为什么提示p对象没有age这个属性。前面学的实力属性不是可以继承类里面的吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-20 08:49:32 | 显示全部楼层
lc88824 发表于 2024-4-20 07:36
如果举的例子中加个类属性age=10,在intm里面再加一个print(self.age)
把下面t=text()注释掉,直接 ...

P是啥?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-4-20 09:21:06 From FishC Mobile | 显示全部楼层
isdkz 发表于 2024-4-20 08:49
P是啥?

p是作为一个实例引用名称传入参数,就好比p=text()那样。我说的是直接不实例化而是以函数传参把P作为一个实例传入第一个位置
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-20 12:34:53 From FishC Mobile | 显示全部楼层
lc88824 发表于 2024-4-20 09:21
p是作为一个实例引用名称传入参数,就好比p=text()那样。我说的是直接不实例化而是以函数传参把P作为一 ...

使用类调用实例方法的时候它就是不会自动帮你传入,你自己传进去是可以的呀,哪里报错呢,给出完整的代码或截图吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-4-20 13:54:21 | 显示全部楼层
本帖最后由 lc88824 于 2024-4-20 13:56 编辑
isdkz 发表于 2024-4-20 12:34
使用类调用实例方法的时候它就是不会自动帮你传入,你自己传进去是可以的呀,哪里报错呢,给出完整的代码 ...


不选择实例化直接用函数传参形式,这里类方法中self.age 为什么不能读取类属性age  记得 实例中如果没有属性会自动向上类中找,这里把13作为一个实例,就是13=Person()按理来说应该能找出13.age属性18的
屏幕截图 2024-04-20 135251.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-20 18:46:43 | 显示全部楼层
lc88824 发表于 2024-4-20 13:54
不选择实例化直接用函数传参形式,这里类方法中self.age 为什么不能读取类属性age  记得 实例中如果没 ...

13又不是Person的实例,怎么会有age属性?

13是int的实例好吧,所以你说的 13=Person() 从何而来,你确定你真的能执行成功这一句?因为13不符合变量命名规范,它只能作为一个整型字面量

你试试
p = Person()
Person.shilifangfa(p)
这样才是真的把Person的实例传进去了好吧,不是随便传个实例进去就行了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-4-20 20:00:47 | 显示全部楼层
isdkz 发表于 2024-4-20 18:46
13又不是Person的实例,怎么会有age属性?

13是int的实例好吧,所以你说的 13=Person() 从何而来,你 ...

也就是说及时把13换成符合的P字母也还会报错是吧?只能是先用括号的参数 在上边引用一下 p=person()
后,这时p是实在存在的然后再传到person.shilifangfa(p)才能最终成功打印出来是这个理解思路把
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-20 21:59:58 From FishC Mobile | 显示全部楼层    本楼为最佳答案   
lc88824 发表于 2024-4-20 20:00
也就是说及时把13换成符合的P字母也还会报错是吧?只能是先用括号的参数 在上边引用一下 p=person()
...

对呀,总的来说得是 Person 的实例才应该传给 Person 的实例化方法的 self

加个括号就是实例化,比如 p = Person() 就是把 Person 实例化并赋给 p
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-6-18 19:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表