【问题标题】:Using self in python, outside of a class在python中使用self,在类之外
【发布时间】:2014-10-16 15:46:58
【问题描述】:

我有点不确定如何在课堂之外使用 self。 python中的很多内置方法都使用self作为参数,不需要你声明类;例如,您可以使用string.upper() 命令将每个字母大写,而无需告诉python 使用哪个类。如果我没有很好地解释自己,我在下面包含了我的代码。

def ispalendrome(self): return self == self[::-1]

largestProd = 999**2
largest5Palendromes = []
while len(largest5Palendromes) <= 5:
    if str(largestProd).ispalendrome(): largest5Palendromes.append(largestProd)
    largestProd -= 1
print largest5Palendromes

注意:我知道还有其他方法可以完成这项任务,但我想知道这是否可行。 TYVM。

【问题讨论】:

  • 您的意思是您想知道是否可以向str() 类型添加新方法。答案是:不,不是直接的,你必须子类化。
  • 究竟是什么问题或在这里不起作用?
  • @MartijnPieters 很好,他可以使用github.com/clarete/forbiddenfruit ...但只是因为你可以并不意味着你应该
  • @JoranBeasley:哎呀,不知道那个项目。是的,仍然不是我实际使用的东西,但很酷。

标签: python python-2.7 self


【解决方案1】:

使用https://github.com/clarete/forbiddenfruit

from forbiddenfruit import curse
def ispalendrome(self): #note that self is really just a variable name ... it doent have to be named self
    return self == self[::-1]
curse(str, "ispalendrome",ispalendrome)

"hello".ispalendrome()

请注意,仅仅因为你可以并不意味着它是一个好主意

或者直接做会好得多

def ispalendrome(a_string):
    return a_string == a_string[::-1]

ispalendrome("hello")

【讨论】:

  • 它被称为“诅咒”是有原因的!
  • 我应该把免责声明加粗吗? :P
  • @JoranBeasley 您可能想看看 3.4 中的新 DynamicClassAttribute。那是真的邪恶的。
【解决方案2】:

Self 没有特殊含义——它只是一个变量名。它在类中的使用只是传统的(因此在其他地方使用它可能会造成混淆)。

但是,您可以事后设置类的属性,这些属性可以是类方法或实例方法(后者按惯例带有“self”)。这不适用于像str 这样的内置类,尽管[编辑:所以你必须“诅咒”或子类,请参阅其他答案]

【讨论】:

    【解决方案3】:

    def ispalendrome(self)
    

    没有必要将参数命名为self(确实有点误导),因为这不是实例方法。我会称它为s(用于字符串):

    def is_palindrome(s):
    

    您可能指的是在类上使用绑定方法,其中:

    an_instance = TheClass()
    an_instance.instance_method() # self is passed implicitly
    

    相当于:

    an_instance = TheClass()
    TheClass.instance_method(an_instance) # self is passed explicitly
    

    在这种特殊情况下,例如:

    >>> "foo".upper()
    'FOO'
    >>> str.upper("foo")
    'FOO'
    

    【讨论】:

      【解决方案4】:

      感觉就像你想用猴子修补一个方法。如果是这样,那么欢迎来到黑暗面的年轻人。让我们开始被诅咒的仪式。本质上你想要猴子补丁。我们只需要一点猴子血。只是在开玩笑。我们需要type.MethodType。但请注意,您不能修改标准库类型:

      >>> from types import MethodType
      >>> def palindrome(self): return self == self[::-1]
      ...
      >>> str.palindrome = MethodType(palindrome, str)
      Traceback (most recent call last):
        File "<input>", line 1, in <module>
      TypeError: can't set attributes of built-in/extension type 'str'
      

      但这不会阻止你在其他课程中造成严重破坏:

      >>> class String(object):
      ...     def __init__(self, done):
      ...         self.done = done
      ...
      ...
      ...
      >>> s = String("stanley yelnats")
      >>> def palindrome(self): return self.done[::-1]
      >>> s.palindrome = MethodType(palindrome, s)
      >>> s.palindrome()
      'stanley yelnats'
      

      你知道这有多容易吗?但我们才刚刚开始。这只是一个例子,现在让我们杀死 class 好吗?下一部分会让你狂笑:

      >>> from types import DynamicClassAttribute
      >>> class String(object):
      ...     def __init__(self, done):
      ...         self.done = done
      ...
      ...
      ...
      >>> s = String("cheese")
      >>> def palindrome(self): return self.done[::-1];
      ...
      >>> String.palindrome = DynamicClassAttribute(palindrome)
      >>> s.palindrome
      'eseehc'
      

      在这之后,如果你不觉得邪恶。那你一定要来我的邪恶巢穴,在那里我会给你展示更多的邪恶技巧并分享cookies

      【讨论】:

        【解决方案5】:

        在 Python 中,类方法的第一个参数是对象实例本身,按照惯例,它被称为 self。您应该避免将self 用于其他目的。

        更详细的解释:

        如果你有课

        class A(object):
            def __init__(self):
                self.b = 1
        

        然后你创建它的一个实例:

        a = A()
        

        这将调用 init 方法和参数 self 如果填充了新对象。然后调用self.b = 1 并将属性b 添加到新对象。然后这个对象将被称为a

        【讨论】:

          【解决方案6】:

          “self”是函数的第一个参数的名称 - 与任何参数一样,它在该函数之外没有任何意义。它对应的是调用该函数的对象。

          【讨论】:

            猜你喜欢
            • 2021-01-06
            • 2021-05-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-09-05
            • 1970-01-01
            • 2011-06-04
            • 2021-04-30
            相关资源
            最近更新 更多