Python 当我使用'__插槽';
最近我学习Python,但我有一个关于Python 当我使用'__插槽';,python,Python,最近我学习Python,但我有一个关于\uuuuuuuuuuuuuuuuuuuuu的问题。在我看来,这是为了限制类中的参数,但也限制类中的方法 例如: from types import MethodType Class Student(object): __slots__=('name','age') 当我运行代码时: def set_age(self,age): self.age=age stu=Student() stu.set_age=MethodType(set_age,s
\uuuuuuuuuuuuuuuuuuuuu
的问题。在我看来,这是为了限制类中的参数,但也限制类中的方法
例如:
from types import MethodType
Class Student(object):
__slots__=('name','age')
当我运行代码时:
def set_age(self,age):
self.age=age
stu=Student()
stu.set_age=MethodType(set_age,stu,Student)
print stu.age
An error has occurred:
stu.set_age=MethodType(set_age,stu,Student)
AttributeError: 'Student' object has no attribute 'set_age'
我想知道,为什么不为这个类使用set_age?您的属性确实没有属性
set_age
,因为您没有为它创建插槽。你期待什么
另外,它应该是
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
class Student(object):
__slots__ = ('name','age')
def set_age(self,age):
self.age = age
其中,set\u age
是Student
类的一种方法,而不是将函数作为一种方法添加到Student
类的实例中。使用\uuuuu slots\uuuuuu
意味着每个类实例都不会得到一个\uuuuu dict\uuu
,因此每个实例都更加轻量级。缺点是不能修改方法,也不能添加属性。你不能做你试图做的事情,也就是添加方法(也就是添加属性)
此外,pythonic方法不是实例化MethodType,而是简单地在类名称空间中创建函数。如果您试图动态添加或修改函数,如在monkey patching中,则只需将函数分配给类,如中所示:
Student.set_age = set_age
当然,将其分配给实例时,如果它使用\uuuuu插槽
,则无法执行此操作
以下是\uuuuuuuuuuuuuuuuuu
文档:
在新样式类中,方法不是实例属性。相反,它们是通过定义\uuu get\uuu
方法遵循的类属性。方法调用obj.some\u method(arg)
相当于obj.\uu class\uuuj.method.\uu get\uuj(obj)(arg)
,这反过来又相当于obj.\uu class\uuj.method(obj,arg)
。\uuuu get\uuu
实现执行实例绑定(在调用方法时,将obj
作为第一个参数粘贴到中)
在示例代码中,您将尝试将手动绑定的方法作为已存在实例的实例变量。这不起作用,因为您的\uuuu\uuu
声明阻止您添加新实例属性。但是,如果您改为向类写信,则不会有任何问题:
class Foo(object):
__slots__ = () # no instance variables!
def some_method(self, arg):
print(arg)
Foo.some_method = some_method # this works!
f = Foo()
f.some_method() # so does this
如果您在将方法添加到其类之前创建了实例,则此代码也可以工作。我使用以下方法代替\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。它只允许使用一组预定义的参数:
class A(object):
def __init__(self):
self.__dict__['a']=''
self.__dict__['b']=''
def __getattr__(self,name):
d=getattr(self,'__dict__')
if d.keys().__contains__(name):
return d.__dict__[attr]
else:
raise AttributeError
def __setattr__(self,name,value):
d=getattr(self,'__dict__')
if d.keys().__contains__(name):
d[name] = value
else:
raise AttributeError
使用getattr(..)
是为了避免递归
在内存和速度方面,《代码》与《代码》相比有一些优点,但这很容易实现和阅读。这似乎已经得到了回答:正如@Thorcourder的链接所说,\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
主要用于在创建一大堆属性受约束。你不应该用它来限制用户可以设置的属性。还有一个有趣的问题。赵,欢迎来到StackOverflow!如果我回答了您的问题,您可以通过单击旁边的复选标记来接受它,它将为您的代表添加+2。祝您在学习Python时好运!对不起,我写错了单词“槽”。我已经改正了。虽然这是一个好的观点,但它并不是一个真正的答案。也许您可以更改代码周围的文本,使其成为一个?否则,它可能应该是一个注释(唉,没有代码)。