Python中类的实例化问题请教

class MyType(type):

def init(self, what, bases=None, dict=None):

print(‘call myType.init()’) #语句 1
super().init(what, bases, dict)


def new(cls, name, bases, attrs):

print(“call MyType.new()”) #语句 2
return type.new(cls, name, bases, attrs)


def call(self, *args, **kwargs):
print(“MyType.call”)

class Foo(object, metaclass=MyType):

def init(self, name=None):

self.name = name

print(“Foo self.name=”, self.name)


def new(cls, *args, **kwargs):

print(“Foo.new cls=”, cls)

return(object.new(cls, *args, **kwargs))


def call(self, cls):

print(“Foo.call cls=”, cls)




if name == ‘main’:

print("---------test---------") #语句 3

obj=Foo() #语句 4



上面代码在 PYTHON3.6 中输出如下:
call MyType.new() #语句 2 的输出
call myType.init() #语句 1 的输出

---------test---------
MyType.call #语句 4 的输出


我的问题如下:
1、当 PYTHON 加载模块的时候,是否就会自动执行类定义中的 init__和__new__方法,以此实现为类分配内存的目的?
2、为何语句 4 “ obj=Foo()” 会导致__call__方法的执行?
我看了一些博文,都提到“对象=类名()”这样的语句是不应该导致__call__执行的,只有“对象()”以及“类名()()”这两种语句才会触发__call

上面语句 4 的输出是怎么回事呢?

感谢指点!
Python中类的实例化问题请教


5 回复

顺便问一下,为何我在外面编辑好的代码包含了缩进,一贴到论坛里就体现不出缩进了?


在Python中,类的实例化是通过调用类来创建对象的过程。核心语法是 实例名 = 类名(),这会触发类的 __init__ 方法(构造函数)进行初始化。

基本示例:

class MyClass:
    def __init__(self, value):
        self.value = value
        print(f"实例已创建,value = {value}")

# 实例化
obj = MyClass(10)
print(obj.value)  # 输出: 10

关键点:

  1. __init__ 不是必须的,但通常用来设置实例属性。
  2. self 代表实例本身,是类方法的第一个参数(约定俗成)。
  3. 实例化时参数会传递给 __init__

稍微复杂点的例子,展示带默认参数和方法的类:

class Person:
    def __init__(self, name, age=18):
        self.name = name
        self.age = age

    def introduce(self):
        return f"我叫{self.name},今年{self.age}岁。"

# 实例化
p1 = Person("张三")
p2 = Person("李四", 25)

print(p1.introduce())  # 输出: 我叫张三,今年18岁。
print(p2.introduce())  # 输出: 我叫李四,今年25岁。

如果你遇到的具体问题是传参报错、__init__没执行、或者实例属性访问不了,八成是语法或缩进弄错了。 把代码贴出来看看。

附加问题:你需要使用 markdown,代码块儿是’’’ 1⃣️那个键位。
1. 先调用__new__。但是很少有人这么写,因为一般都用不到。参见 stackoverflow 上关于 new 的问题。然后调用 init。是不是分配内存,我没研究过,不妄言
2.obj=Foo()==Foo.call()

要用 Markdown 格式包围代码才能保证缩进,而且仅对发帖有效,回帖不支持 Markdown

感谢,但是我越发糊涂了。
我看了这篇博文 http://python.jobbole.com/83747/
博文的“ 5.call”小节写了这段话:“注:构造方法的执行是由创建对象触发的,即:对象=类名();而对于__call__方法的执行是由对象后加括号触发的,即:对象()或者类()()”

就是因为看了这段话,结合这个程序,我才觉得有问题,obj=Foo()这个语句应该是博文中的 对象=类名() 这个形式,所以不应该调用 Foo.call()方法才对啊?
关于这个观点,我还有一个例子可以说明,比如下面这段代码和对应的输出,请注意语句 1 就是一个把对象实例化的语句,这个语句并没有调用类的__call__()方法:

class Deco:
def init(self,func):
self.func=func
print(“init__执行完毕。func=",self.func)
def call(self,*arg,**arg2):
print("开始执行__call
。”)
self.func(‘abc’)
print(self,arg,arg2)

class MyCls():

def myFunc(self):
print(‘this is my work arg is %s’%self)

mycls=MyCls()
deco=Deco(mycls.myFunc) #语句 1

代码输出如下:
__init__执行完毕。func= <function MyCls.myFunc at 0x01C49AE0>
__init__执行完毕。func= <main.Deco object at 0x01C4B190>

回到顶部