首页 > 编程语言 >Python魔力方法

Python魔力方法

时间:2023-03-30 22:55:13浏览次数:46  
标签:__ 魔力 Python self print 方法 def name

Python的魔术方法(Magic Methods)也称为双下划线方法(double underscore method),以双下划线开头和结尾,用于重载类的特殊行为。可以使类的实例对象表现出像内置类型的行为,如加、减、乘、切片、比较等,增加代码的可读性和可维护性。以下是Python中一些重要的魔术方法:

1.__init__方法

__init__(self[, ...])方法在创建类的实例对象时自动调用,用于进行初始化操作,为实例对象的属性设置初始值。其中,self代表实例对象本身。此外,__new__方法在创建类的实例对象之前被调用,可以用来进行一些定制化的操作。

示例:

class MyClass:
    def __init__(self, name):
        self.name = name

obj = MyClass("Tom")
print(obj.name)  # 输出 Tom

2.__call__方法

__call__(self[, ...])方法使得对象可以像函数一样被调用,用于对实例对象添加可调用特性。一般情况下,Python中的函数即对象,而__call__方法可以让实例对象也表现得像函数。

示例:

class MyClass:
    def __call__(self):
        print("Hello, I can be called like a function.")

obj = MyClass()
obj()  # 输出:Hello, I can be called like a function.

3.__str____repr__方法

__str__(self)方法返回一个字符串,用于自定义实例对象的字符串输出格式。__repr__(self)方法也返回一个字符串,表示对实例对象进行计算或操作的表达式或字符串,通常被用于调试和日志输出。

示例:

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

    def __str__(self):
        return f"{self.name}, {self.age} years old."

    def __repr__(self):
        return f"Person(name={self.name}, age={self.age})"

p = Person("Tom", 18)
print(str(p))  # 输出:Tom, 18 years old.
print(repr(p))  # 输出:Person(name=Tom, age=18)

4.__add____sub____mul____div__(加减乘除)

__add__(self, other)方法表示“加”,用于定义对象的加法行为,self代表第一个加数,other代表第二个加数。类似的,有__sub____mul____div__等方法表示减、乘、除等。

示例:

class Vector:
    def __init__(self, x=None, y=None):
        self.x = x
        self.y = y

    def __add__(self, other):
        x = self.x + other.x
        y = self.y + other.y
        return Vector(x, y)

    def __str__(self):
        return f"({self.x}, {self.y})"

v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1 + v2)  # 输出:(4, 6)

5.__len__方法

__len__(self)方法用于定义实例对象的长度,返回一个整数,即对象中元素的数量。常用于定制容器类型的大小。

示例:

class MyClass:
    def __init__(self, lst=None):
        self.lst = lst

    def __len__(self):
        return len(self.lst)

obj = MyClass([1, 2, 3])
print(len(obj))  # 输出:3

6.__getitem____setitem____delitem__方法

__getitem__(self, key)方法和__setitem__(self, key, value)方法定义了实例对象的索引和切片功能,__delitem__(self, key)方法用于实现删除操作。其中,key表示索引或切片范围,value表示要赋值的值。

示例:

class MyList:
    def __init__(self, lst=None):
        self.lst = lst if lst else []

    def __getitem__(self, index):
        return self.lst[index]

    def __setitem__(self, index, value):
        self.lst[index] = value

    def __delitem__(self, index):
        del self.lst[index]

    def __len__(self):
        return len(self.lst)

lst = MyList([1, 2, 3])
print(lst[1])   # 输出:2
lst[1] = 5
print(lst[1])   # 输出:5
del lst[0]
print(len(lst))  # 输出:2

7.__iter____next__方法

__iter__(self)方法返回一个可迭代对象,用于定义实例对象的迭代行为。__next__(self)方法用于定义实例对象的下一个元素是什么,具体包括迭代开始、迭代状态以及迭代结束时所需的返回值。

示例:

class Fibonacci:
    def __init__(self, n):
        self.n = n
        self.current = 0
        self.next = 1

    def __iter__(self):
        return self

    def __next__(self):
        if self.current + self.next > self.n:
            raise StopIteration
        self.current, self.next = self.next, self.current + self.next
        return self.current

for i in Fibonacci(100): 
    print(i, end=' ')  # 输出:1 1 2 3 5 8 13 21 34 55 89

8.__getattr____setattr__方法

__getattr__(self, attr)方法用于获取实例对象的属性,当代码中使用了实例对象没有的属性时,该方法会被调用,如果没有定义该方法,则会抛出AttributeError异常。__setattr__(self, attr, value)方法用于设置实例对象的属性,当代码中设置实例对象没有的属性时,该方法会被调用。

示例:

class MyClass:
    def __init__(self, name):
        self.name = name

    def __getattr__(self, attr):
        return f"{attr} 属性不存在。"

    def __setattr__(self, attr, value):
        if attr == "name":
            self.__dict__[attr] = value.upper()
        else:
            self.__dict__[attr] = value

obj = MyClass("Tom")
print(obj.name)  # 输出:TOM
print(obj.age)   # 输出:age 属性不存在。

9.__enter____exit__方法

__enter__(self)方法会在进入with语句时被调用,用于进行一些初始化操作,同时该方法需要返回一个上下文管理器对象。__exit__(self, exc_type, exc_value, traceback)方法会在离开with语句时被调用,用于进行一些清理操作。

示例:

class File:
    def __init__(self, filename):
        self.filename = filename

    def __enter__(self):
        self.f = open(self.filename, "r")
        return self.f

    def __exit__(self, exc_type, exc_value, traceback):
        self.f.close()

with File("test.txt") as f:
    content = f.read()
    print(content)

10.__eq____lt____le__等比较方法

__eq__(self, other)方法用于定义等于运算符==__lt__(self, other)__le__(self, other)__gt__(self, other)__ge__(self, other)方法分别用于定义小于、小于等于、大于、大于等于运算符。

示例:

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

    def __eq__(self, other):
        return self.age == other.age

    def __lt__(self, other):
        return self.age < other.age

p1 = Person("Tom", 18)
p2 = Person("Jerry", 20)
print(p1 == p2)  # 输出:False
print(p1 < p2)   # 输出:True

11.__hash____call__方法

__hash__(self)方法定义了实例对象的hash值,通常用于优化字典、集合等操作。__call__(self)方法定义了实例对象的调用过程,用于将实例对象作为函数调用时的行为。

示例:

class MyClass:
    def __init__(self, attr):
        self.attr = attr

    def __hash__(self):
        return hash(self.attr)

    def __call__(self):
        print(f"The attribute is {self.attr}.")

obj1 = MyClass(1)
obj2 = MyClass(2)
print(hash(obj1))  # 输出:1
print(hash(obj2))  # 输出:2

obj1()  # 输出:The attribute is 1.

12.__format__方法

__format__(self, format_spec)方法用于自定义实例对象的格式化,其中format_spec为格式化字符串。

示例:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __format__(self, format_spec):
        if format_spec == "r":
            return f"({self.y}, {self.x})"
        else:
            return f"({self.x}, {self.y})"

p = Point(1, 2)
print(format(p))    # 输出:(1, 2)
print(format(p, "r"))  # 输出:(2, 1)

13.__dir__方法

__dir__(self)方法用于自定义类的dir()函数返回的属性列表,默认情况下会返回类的所有属性和方法,包括从父类继承的。

示例:

class MyClass:
    def __init__(self, name):
        self.name = name

    def foo(self):
        pass

    def __dir__(self):
        return [attr for attr in dir(self.__class__) if not attr.startswith("__")]

obj = MyClass("Tom")
print(dir(obj))  # 输出:['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'foo', 'name']

在上述示例中,__dir__方法返回了类的所有属性和方法,但排除了以__开头的魔术方法。

14.__init_subclass__方法

__init_subclass__(cls, **kwargs)方法在每个子类被创建时被调用,通常用于对子类进行初始化或配置。

示例:

class BaseClass:
    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        print(f"Creating subclass {cls.__name__}")

class SubClass1(BaseClass):
    pass

class SubClass2(BaseClass):
    pass

# 输出:Creating subclass SubClass1
#       Creating subclass SubClass2

在上述示例中,当子类SubClass1SubClass2被创建时,会自动调用__init_subclass__方法,并输出相应的信息。

15.__set_name__方法

__set_name__(self, owner, name)方法在类的属性被设置时被调用,通常用于对属性进行验证或初始化。注意,该方法只在 Python 3.6 及以上版本中可用。

示例:

class Validator:
    def __set_name__(self, owner, name):
        self.name = name

    def __get__(self, obj, owner):
        return obj.__dict__[self.name]

    def __set__(self, obj, value):
        if value < 0:
            raise ValueError(f"{self.name} should be greater than 0.")
        obj.__dict__[self.name] = value

class MyClass:
    x = Validator()

obj = MyClass()
obj.x = 1
print(obj.x)  # 输出:1
obj.x = -1   # 抛出 ValueError 异常

在上述示例中,Validator类的__set_name__方法会将属性名保存在name属性中,然后通过__get____set__方法对属性进行访问和设置。这里通过设置x属性来演示__set_name__方法的应用,如果设置的值小于 0,则抛出ValueError异常。

16.__new__方法

__new__(cls, *args, **kwargs)方法是一个特殊的静态方法,用于创建类的实例对象,通常用于自定义类的实例化过程。该方法会返回创建的新实例对象,然后调用__init__方法进行初始化。

示例:

class Singleton:
    instance = None

    def __new__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance = super().__new__(cls, *args, **kwargs)
            return cls.instance
        else:
            return cls.instance

    def __init__(self, name):
        self.name = name

obj1 = Singleton("Tom")
obj2 = Singleton("Jerry")
print(obj1 == obj2)  # 输出:True
print(obj1.name)     # 输出:Tom
print(obj2.name)     # 输出:Tom

在上述示例中,Singleton类通过重写__new__方法,实现了单例模式,保证每次实例化时返回的都是同一个实例对象。

标签:__,魔力,Python,self,print,方法,def,name
From: https://www.cnblogs.com/zouzhibin/p/17274674.html

相关文章

  • python基础学习总结
    python关键字也是以下划线或者字母开头。python关键字可以通过导包获取关键字如下: ['False','None','True','and','as','assert','async','await','break','class','continue'......
  • axios获取不到response返回的响应的解决方法
    今天在用mybatis+vue+axios写登录界面的时候,发现用户名还有密码的数据都能够传输到servlet里,但是当servlet对html界面进行相应的时候,axios却收不到消息,经过长时间的排查后也没有发现问题,终于在今晚的百度下发现了结果,上原文:解决方法经过检查发现,我的button按钮果然没有type属性,......
  • 集合的常用方法
    1.add方法:向集合中添加元素set1={'apple','banana','cherry'}set1.add('orange')print(set1)#{'apple','cherry','banana','orange'}2.clear方法:清空集合中的所有元素set1={'apple'......
  • 字典常用方法
    1.clear方法:清空字典中的所有键值对dict1={'name':'Tom','age':25,'city':'Beijing'}dict1.clear()print(dict1)#{}2.copy方法:复制字典dict1={'name':'Tom','age':25,'city'......
  • 字符串常用方法
    1.capitalize()方法:将字符串的首字母大写。str="hello,world"print(str.capitalize())输出:Hello,world2.casefold()方法:将字符串转换为小写并删除所有大小写特有的字符,使字符串可以比较。str="Hello,WORLD"print(str.casefold())输出:hello,world3.center()方......
  • main 方法的执行过程
    参考https://www.cnblogs.com/max-home/p/12270183.htmlCS-NotesJavaGuide1、执行流程publicclassTest{publicstaticvoidmain(String[]args){Studentstudent=newStudent("abcd");student.sayName();}}classStudent{......
  • 中文设置成粗体的方法
    在xml文件中使用android:textStyle="bold"可以将英文设置成粗体,但是不能将中文设置成粗体,将中文设置成粗体的方法是:TextViewtv=(TextView)findViewById(R.id.TextView01);TextPainttp=tv.getPaint();tp.setFakeBoldText(true);......
  • java.lang.String中的trim()方法的…
    String.Trim()方法到底为我们做了什么,仅仅是去除字符串两端的空格吗?一直以为Trim()方法就是把字符串两端的空格字符给删去,其实我错了,而且错的比较离谱。首先我直接反编译String类,找到Trim()方法:publicstringTrim(){returnthis.TrimHelper(WhitespaceChars,2);}Trim......
  • [Python]异步回调函数
    importasynciofromfunctoolsimportpartialfromasyncioimportFutureasyncdeff1():print(1)awaitasyncio.sleep(2)print(2)return"f1"defcallback1(future:Future):print(future.result())print("我是f1的回调函数&......
  • Python 3 vs Python 2 All In One
    Python3vsPython2AllInOnePython3.x与Python2.x版本区别https://www.runoob.com/python/python-2x-3x.htmlhttps://www.datacamp.com/blog/python-2-vs-3-everything-you-need-to-knowprintvsprint()如果Python2.x版本想使用使用Python3.x的print函......