一静态方法 (staticmethod) 和类方法(classmethod)
类方法: 有个默认参数 cls, 并且可以直接用类名去调用, 可以与类属性交互(也就是可以使用类属性)
静态方法: 让类里的方法直接被类调用, 就像正常调用函数一样
类方法和静态方法的相同点: 都可以直接被类调用, 不需要实例化
类方法和静态方法的不同点:
类方法必须有一个 cls 参数表示这个类, 可以使用类属性
静态方法不需要参数
绑定方法: 分为普通方法和类方法
普通方法: 默认有一个 self 对象传进来, 并且只能被对象调用 ------- 绑定到对象
类方法: 默认有一个 cls 对象传进来, 并且可以被类和对象 (不推荐) 调用 ----- 绑定到类
非绑定方法: 静态方法: 没有设置默认参数, 并且可以被类和对象 (不推荐) 调用 ----- 非绑定
- # staticmethod 和 classmethod
- class Student:
- f = open(student, encoding=utf-8)
- def __init__(self):
- pass
- @classmethod #类方法 : 有个默认参数 cls, 并且可以直接使用类名去
- #调用, 还可以与类属性交互(也就是可以使用类属性)
- def show_student_info_class(cls):
- # f = open(student, encoding=utf-8)
- for line in cls.f:
- name,sex = line.strip().split(,)
- print(name,sex)
- @staticmethod #静态方法: 可以直接使用类名去调用, 就像正常的函数调用一样
- def show_student_info_static(): #不用传 self
- f = open(student,encoding=utf-8)
- for line in f:
- name,sex = line.strip().split(,)
- print(name,sex)
- # egon = Student()
- # egon.show_student_info_static() #也可以这样调, 但是还是推荐用类名去调
- # egon.show_student_info_class()
- Student.show_student_info_class()# 类名. 方法名()
- print(-------------------)
- Student.show_student_info_static()# 类名. 方法名()
isinstance 和 issubclass
isinstance(obj,cls): 检查 obj 是不是 cls 的对象(传两个参数, 一个是对象, 一个是类)
issubclass(sub,super): 检查 sub 是不是 super 的子类(传两个参数, 一个是子类, 一个是父类)
- class Foo:
- pass
- class Son(Foo):
- pass
- s = Son()
- print(isinstance(s,Son)) #判断 s 是不是 Son 的对象
- print(type(s) is Son)
- print(isinstance(s,Foo)) #判断 s 是不是 Foo 的对象 不精准
- print(type(s) is Foo) #type 比较精准
- print(issubclass(Son,Foo)) #判断 Son 是不是 Foo 的子类
- print(issubclass(Son,object))
- print(issubclass(Foo,object))
- print(issubclass(int,object))
二反射
反射: 可以用字符串的方式去访问对象的属性, 调用对象的方法(但是不能去访问方法),python 中一切皆对象, 都可以使用反射
反射有四种方法:
hasattr:hasattr(object,name)判断一个对象是否有 name 属性或者 name 方法有就返回 True, 没有就返回 False
getattr: 获取对象的属性或者方法, 如果存在则打印出来 hasattr 和 getattr 配套使用
需要注意的是, 如果返回的是对象的方法, 返回出来的是对象的内存地址, 如果需要运行这个方法, 可以在后面添加一对()
setattr: 给对象的属性赋值, 若属性不存在, 先创建后赋值
delattr: 删除该对象指定的一个属性
- # setattr
- class Foo:
- def __init__(self):
- self.name = egon
- self.age = 51
- def func(self):
- print(hello)
- egg = Foo()
setattr(egg,sex, 男)
- print(egg.sex)
- # 2.
- def show_name(self):
- print(self.name+sb)
- setattr(egg,sh_name,show_name)
- egg.sh_name(egg)
- show_name(egg)
- delattr(egg,name)
- print(egg.name)
1. 对象应用反射
- # 对象应用反射
- class Foo:
- def __init__(self):
- self.name = egon
- self.age = 51
- def func(self):
- print(hello)
- egg = Foo()
- print(hasattr(egg,name)) #先判断 name 在 egg 里面存在不存在
- print(getattr(egg,name)) #如果为 True 它才去得到
- print(hasattr(egg,func))
- print(getattr(egg,func)) #得到的是地址
- # getattr(egg,func)() #在这里加括号才能得到, 因为 func 是方法
- if hasattr(egg,func):
- getattr(egg,func)()
- else:
print(没找到)
2. 类应用反射
- # 类应用反射
- class Foo:
- f = 123
- @classmethod
- def class_method_dome(cls):
- print(class_method_dome)
- @staticmethod
- def static_method_dome():
- print(static_method_dome)
- print(hasattr(Foo,class_method_dome))
- method = getattr(Foo,class_method_dome)
- method()
- print(------------)
- print(hasattr(Foo,static_method_dome))
- method1 = getattr(Foo,static_method_dome)
- method1()
3. 模块应用反射
模块的应用又分为导入其他模块反射和在本模块中反射
- # 1. 导入其他模块引用
- import mymodule
- print(hasattr(mymodule,test))
- getattr(mymodule,test)()
- # # 这里的 getattr(mymodule,test)()这一句相当于
- # p = getattr(mymodule,test)
- # p()
- # 2. 在本模块中应用反射
- def demo1():
- print(wwww)
- import sys
- # print(sys.modules)
- module_obj = sys.modules[__name__] #相当于__main__
- print(module_obj)
- print(hasattr(module_obj,demo1))
- getattr(module_obj,demo1)()
- # 举例
def 注册():
print(regiester)
def 登录():
print(login)
def 购物():
pass
print(注册, 登录, 购物)
ret = input(请输入你要做的操作:)
- import sys
- my_module = sys.modules[__name__] #利用 sys 模块导入一个自己的模块
- if hasattr(my_module,ret):
- getattr(my_module,ret)()
三内置方法
1.__str__和__repr__
改变对象的字符串显示
- # __str__和__repr__
- class Foo:
- def __init__(self,name):
- self.name = name
- def __repr__(self):
- return obj in str #这里只能是 return
- # def __str__(self):
- # return %s obj in str%self.name
- f = Foo(egon)
- print(f) #优先执行__str__里面的内容
- # 那么你是不是据地__repr__没用呢?
- # print(%s%f) #执行的是__str__里面的返回值
- # print(%r%f) #执行的是__repr__里面的返回值
- print(==============)
- print(str(f)) #当执行 str(f)时, 会去找__str__这个方法, 如果找不到的时候,__repr__这个方法就给替补了
- print(repr(f))
- #1. 当打印一个对象的时候, 如果实现了__str__方法, 打印__str__中的返回值
- # 2. 当__str__没有被实现的时候, 就会调用__repr__方法
- # 3. 但是当你用字符串格式化的时候,%s 和 %r 会分别调用__str__和__repr__方法
- # 4. 不管是在字符串格式化的时候还是在打印对象的时候,
- # __repr__方法都可以作为__str__方法的替补, 但反之则不行
- # 5. 用于友好的表示对象如果__str__和__repr__方法你只能实现一个: 先实现__repr__
- 2.__del__
析构方法, 当对象在内存中被释放时, 自动触发执行
注: 此方法一般无须定义, 因为 Python 是一门高级语言, 程序员在使用时无需关心内存的分配和释放, 因为此工作都是交给 Python 解释器来执行, 所以, 析构函数的调用是由解释器在进行垃圾回收时自动触发执行的
- class Foo:
- def __del__(self):
print(执行我啦)
- f= Foo()
- print(123)
- print(123)
- print(123)
- print(123)
3.item 系列
分别有__getitem__ ,__setitem__ ,__delitem__
- class Foo:
- def __init__(self):
- self.name = egon
- self.age = 73
- self.l=[1,2,3]
- def __getitem__(self, item): #得到
- # return self.l[item]
- # return self.__dict__[item]
- # print(Foo.__dict__)
- return 123
- def __setitem__(self, key, value): #修改
- print(key,value)
- self.__dict__[key] = value
- def __delitem__(self, key): #删除
- del self.__dict__[key]
- f = Foo()
- print(f[qqq]) #不管里面放的啥值, 它都会得到返回值的内容, 调用的是__getitem__方法
- f[name]=alex #修改 egon 的值为 alex, 调用 __setitem__方法
- # del f[name] #删除 name, 就会报错了, 说明在调用__delitem__方法调用成功了, 就已经删了, 就会报错了
- print(f.name)
- f1 = Foo()
- print(f == f1)
- # print(f.name)
- # print(f[0]) #一开始不能这样取值, 但是提供了一个__getitem__方法, 这样就可以用了
- # print(f[1])
- # print(f[2])
4.__new__(创建)
- # 单例模式
- # 4.__new__方法
- # 单例模式: 是一种设计模式
- class Singleton:
- def __new__(cls, *args, **kw):
- if not hasattr(cls, _instance):
- orig = super(Singleton, cls)
- cls._instance = orig.__new__(cls, *args, **kw)
- return cls._instance
- one = Singleton()
- two = Singleton()
- print(one,two) #他们两个的地址一样
- one.name = alex
- print(two.name)
- #__new__
- # class A:
- # def __init__(self): #有一个方法在帮你创造 self
- # print(in init function)
- # self.x = 1
- #
- # def __new__(cls, *args, **kwargs):
- # print(in new function)
- # return object.__new__(A, *args, **kwargs)
- # a = A()
- # b = A()
- # c = A()
- # d = A()
- # print(a,b,c,d)
- 5.__call__
对象后面加括号, 触发执行
注: 构造方法的执行是由创建对象触发的, 即: 对象 = 类名() ; 而对于 __call__ 方法的执行是由对象后加括号触发的, 即: 对象() 或者 类()()
- class Foo:
- def __call__(self, *args, **kwargs):
- print(123)
- # f = Foo()
- # f() #如果不写上面的__call__方法, 就不会调用如果加上, 就正确了
- Foo()() #也可以这样表示
- 6.__len__
- 7.__hash__
- class Foo:
- def __hash__(self):
- print(aaaaaaaaaa)
- return hash(self.name)
- # print(aaas)
- f = Foo()
- f.name = egon
- print(hash(f)) #hash 方法是可以重写的
- 8.__eq__
- class A:
- def __eq__(self, other):
- return True
- a = A()
- b = A()
- print(a==b) #不加方法的时候返回的是 False, 加了个__eq__方法就返回了个 True
- # == 内部就调用了__eq__方法
- print(a is b)
一道面试题
- # 纸牌游戏
- from collections import namedtuple
- Card = namedtuple(Card,[rank,suit]) #两个属性: 一个是数, 一个是花色(每一个 card 的对象就是一张纸牌)
- class FranchDeck: #纸牌数据类型
- ranks = [str(n) for n in range(2,11)] + list(JQKA)
suits = [红心, 方板, 梅花, 黑桃]
- def __init__(self):
- self._cards = [Card(rank,suit) for rank in FranchDeck.ranks #先循环这个, 在循环下面的那个循环
- for suit in FranchDeck.suits]
- def __len__(self):
- return len(self._cards)
- def __getitem__(self, item):
- return self._cards[item]
- def __setitem__(self, key, value):
- self._cards[key] = value
- deck = FranchDeck()
- # print(deck[0])
- # print(deck[0])
- # print(deck[0])
- # print(deck[0])
- from random import choice
- print(choice(deck))
- print(choice(deck))
- from random import shuffle
- shuffle(deck)
- print(deck[:5])
来源: http://www.bubuko.com/infodetail-2500692.html