[英]Why does the variable d1 in a function give the error "d1 is not defined" (it was working but now it's not)
[英]Why does “self” outside a function's parameters give a “not defined” error?
看看这段代码:
class MyClass():
# Why does this give me "NameError: name 'self' is not defined":
mySelf = self
# But this does not?
def myFunction(self):
mySelf2 = self
基本上我想要一个类来引用自己而不需要专门命名自己的方法,因此我希望自己为类工作,而不仅仅是方法/函数。 我怎样才能做到这一点?
编辑:这一点是我试图从类内部引用类名称与self之类的东西。 class ._ name _这样类名在代码的任何地方都没有硬编码,因此重用代码更容易。
编辑2:从我从下面的答案中学到的,我想要做的是不可能的。 我必须找到一种不同的方式。 任务放弃了。
编辑3:这是我正在尝试做的事情:
class simpleObject(object):
def __init__(self, request):
self.request = request
@view_defaults(renderer='string')
class Test(simpleObject):
# this line throws an error because of self
myClassName = self.__class__.__name__
@view_config(route_name=myClassName)
def activateTheView(self):
db = self.request.db
foo = 'bar'
return foo
请注意,当您希望类引用自身以使赋值工作时,不会定义self
。 这是因为(除了被任意命名), self
指的是实例而不是类。 在可疑的代码行试图运行的时候,还没有类可以引用它。 不,它会引用类,如果有。
在方法中,您始终可以使用type(self)
。 这将获得创建当前实例的MyClass
的子类。 如果要对MyClass
进行硬编码,则该名称将在方法的全局范围内可用。 这将允许您执行示例在实际工作时允许的所有内容。 例如,您可以在方法中执行MyClass.some_attribute
。
您可能希望在创建类之后修改类属性。 这可以通过装饰器或临时基础来完成。 元类可能更适合。 虽然不知道你真正想做什么,但这是不可能的。
这里有一些代码可以做你想要的。 它使用元类AutoViewConfigMeta
和一个新的装饰器来标记您希望view_config
应用于的方法。 我欺骗了view_config
装饰器。 它会在调用时打印出类名,以证明它可以访问它。 元类__new__
只循环遍历类字典并查找由auto_view_config
装饰器标记的方法。 它清除没谱,并应用view_config
用适当的类名装饰。
这是代码。
# This just spoofs the view_config decorator.
def view_config(route=''):
def dec(f):
def wrapper(*args, **kwargs):
print "route={0}".format(route)
return f(*args, **kwargs)
return wrapper
return dec
# Apply this decorator to methods for which you want to call view_config with
# the class name. It will tag them. The metaclass will apply view_config once it
# has the class name.
def auto_view_config(f):
f.auto_view_config = True
return f
class AutoViewConfigMeta(type):
def __new__(mcls, name, bases, dict_):
#This is called during class creation. _dict is the namespace of the class and
# name is it's name. So the idea is to pull out the methods that need
# view_config applied to them and manually apply them with the class name.
# We'll recognize them because they will have the auto_view_config attribute
# set on them by the `auto_view_config` decorator. Then use type to create
# the class and return it.
for item in dict_:
if hasattr(dict_[item], 'auto_view_config'):
method = dict_[item]
del method.auto_view_config # Clean up after ourselves.
# The next line is the manual form of applying a decorator.
dict_[item] = view_config(route=name)(method)
# Call out to type to actually create the class with the modified dict.
return type.__new__(mcls, name, bases, dict_)
class simpleObject(object):
__metaclass__ = AutoViewConfigMeta
class Test(simpleObject):
@auto_view_config
def activateTheView(self):
foo = 'bar'
print foo
if __name__=='__main__':
t = Test()
t.activateTheView()
如果您有任何疑问,请告诉我。
Python有一个“明显比隐含更好”的设计理念。
许多语言中具有方法,该方法的范围的隐式指针或变量(例如this
其是指通过调用该方法的对象在C ++)。 Python没有这个。 这里,所有绑定方法都将有一个额外的第一个参数,该参数是调用该方法的对象。 你可以称它为任何你想要的( self
不是像关键字this
在C ++中)。 名称self
是约定而不是语法规则。
你的方法myFunction
将变量self
定义为参数,因此它可以工作。 在班级没有这样的变量,所以它出错了。
这么多的解释。 我不知道你做你想做的直接方式,我从来没有在Python中看到过这样的要求。 你能详细解释为什么要做这样的事吗? 也许假设您正在制作哪些可以使用Python以另一种方式处理。
self
只是一个名字,在这种情况下你的self
是一个类变量而不是用于调用它的对象,
self
被视为一个普通变量,并且没有定义,因为函数中的self来自用于调用的对象。
您希望将self
的对象引用视为不可能的类变量。
self
不是关键字,它只是一种约定。 这些方法是类对象(不是实例)的属性,但它们将实例作为第一个参数接收。 如果你愿意,可以将参数重命名为xyzzy
,它仍然可以以相同的方式工作。
但是(显而易见)你不能引用方法体外的方法参数。 在class
块内,但在任何方法之外, self
是未定义的。 这个概念甚至没有意义 - 在评估class
块时,还没有可能存在类的实例。
因为名称self
被明确定义为myFunction
参数的一部分。 方法的第一个参数是调用该方法的实例; 在类体中,没有“我们正在处理的实例”,因为类主体处理类的每个可能的实例(包括那些不一定存在的实例) - 所以,没有可称为self
特定对象。
如果你想引用类本身 ,而不是它的一些实例,那么拼写为self.__class__
class__(或者,对于Py2中的新式类和Py3中的所有类, type(self)
) self
存在。 如果您希望能够在不存在self
情况下处理此问题,那么您可能希望查看与任何特定实例无关的类方法 ,因此请使用类本身代替self
。 如果你真的需要在类体中这样做(并且你可能没有),你只需要按名称调用它。
您不能在类主体中引用类本身,因为在执行类主体时类不存在。 (如果前面的句子令人困惑,那么阅读有关元类的内容将会清除它或者让你更加困惑。)
在实例方法中,您可以使用self.__class__
引用实例的类,但请注意这里。 这将是实例的实际类,它通过继承的力量可能不是定义方法的类。
在类方法中,类作为第一个参数传入,就像实例是实例方法的第一个参数一样:
class MyClass(object):
@classmethod
def foo(cls):
print cls.__name__
MyClass.foo() # Should print "MyClass"
与实例方法一样,实际类可能因继承而不同。
class OtherClass(MyClass):
pass
OtherClass.foo() # Should print "OtherClass"
如果你真的需要参考MyClass
的方法中MyClass
,你几乎将不得不把它称为MyClass
,除非你使用魔法。 这种魔法比它的价值更麻烦。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.