1. 程式人生 > 實用技巧 >Java氣泡排序法-優化演算法

Java氣泡排序法-優化演算法

元類

一切源自於一句話:python中一切皆為物件
一:元類介紹

"""

元類=》OldboyTeacher類=》obj

程式碼

class OldboyTeacher(object):
school = 'oldboy'

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

def say(self):
print('%s says welcome to the oldboy to learn Python' % self.name)


obj = OldboyTeacher('egon', 18) # 呼叫OldboyTeacher類=》物件obj

呼叫元類=》OldboyTeacher類
print(type(obj))

print(type(OldboyTeacher))

結論:預設的元類是type,預設情況下我們用class關鍵字定義的類都是由type產生的

"""

二:class關鍵字底層的做了哪些事

'''

1、先拿到一個類名

class_name = "OldboyTeacher"

2、然後拿到類的父類

class_bases = (object,)

3、再執行類體程式碼,將產生的名字放到名稱空間中
class_dic = {}
class_body = """
school = 'oldboy'

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

def say(self):
print('%s says welcome to the oldboy to learn Python' % self.name)
"""
exec(class_body,{},class_dic)

print(class_dic)

4、呼叫元類(傳入類的三大要素:類名、基類、類的名稱空間)得到一個元類的物件,然後將元類的物件賦值給變數名OldboyTeacher,oldboyTeacher就是我們用class自定義的那個類

OldboyTeacher = type(class_name,class_bases,class_dic)

'''

三:自定義元類

'''
class Mymeta(type): # 只有繼承了type類的類才是自定義的元類
pass

class OldboyTeacher(object, metaclass=Mymeta):
school = 'oldboy'

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

def say(self):
print('%s says welcome to the oldboy to learn Python' % self.name)

1、先拿到一個類名:"OldboyTeacher"

2、然後拿到類的父類:(object,)
3、再執行類體程式碼,將產生的名字放到名稱空間中{...}
4、呼叫元類(傳入類的三大要素:類名、基類、類的名稱空間)得到一個元類的物件,然後將元類的物件賦值給變數名OldboyTeacher,oldboyTeacher就是我們用class自定義的那個類

OldboyTeacher = Mymeta("OldboyTeacher",(object,),{...})
'''

四:自定義元類來控制OldboyTeacher類的產生

'''
import re

class Mymeta(type): # 只有繼承了type類的類才是自定義的元類
def init(self, class_name, class_bases, class_dic):
# print(self) # 類<class 'main.OldboyTeacher'>
# print(class_name)
# print(class_bases)
# print(class_dic)

   if not re.match("[A-Z]", class_name):
raise BaseException("類名必須用駝峰體")

if len(class_bases) == 0:
raise BaseException("至少繼承一個父類")

# print("文件註釋:",class_dic.get('__doc__'))
doc=class_dic.get('__doc__')

if not (doc and len(doc.strip()) > 0):
raise BaseException("必須要有檔案註釋,並且註釋內容不為空")

OldboyTeacher = Mymeta("OldboyTeacher",(object,),{...})

class OldboyTeacher(object,metaclass=Mymeta):
"""
adsaf
"""

school = 'oldboy'

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

def say(self):
print('%s says welcome to the oldboy to learn Python' % self.name)

'''

五:自定義元類來控制OldboyTeacher類的呼叫

'''
import re

class Mymeta(type): # 只有繼承了type類的類才是自定義的元類
def init(self, class_name, class_bases, class_dic):
# print(self) # 類<class 'main.OldboyTeacher'>
# print(class_name)
# print(class_bases)
# print(class_dic)

   if not re.match("[A-Z]", class_name):
raise BaseException("類名必須用駝峰體")

if len(class_bases) == 0:
raise BaseException("至少繼承一個父類")

# print("文件註釋:",class_dic.get('__doc__'))
doc = class_dic.get('__doc__')

if not (doc and len(doc.strip()) > 0):
raise BaseException("必須要有檔案註釋,並且註釋內容不為空")

# res = OldboyTeacher('egon',18)
def __call__(self, *args, **kwargs):
# 1、先建立一個老師的空物件
tea_obj = object.__new__(self)
# 2、呼叫老師類內的__init__函式,然後將老師的空物件連同括號內的引數的引數一同傳給__init__
self.__init__(tea_obj, *args, **kwargs)
tea_obj.__dict__ = {"_%s__%s" %(self.__name__,k): v for k, v in tea_obj.__dict__.items()}

# 3、將初始化好的老師物件賦值給變數名res
return tea_obj
OldboyTeacher = Mymeta("OldboyTeacher",(object,),{...})

class OldboyTeacher(object, metaclass=Mymeta):
"""
adsaf
"""

school = 'oldboy'

# tea_obj,'egon',18
def __init__(self, name, age):
self.name = name # tea_obj.name='egon'
self.age = age # tea_obj.age=18

def say(self):
print('%s says welcome to the oldboy to learn Python' % self.name)

res = OldboyTeacher('egon', 18)
print(res.dict)

print(res.name)
print(res.age)
print(res.say)
呼叫OldboyTeacher類做的事情:
1、先建立一個老師的空物件
2、呼叫老師類內的init方法,然後將老師的空物件連同括號內的引數的引數一同傳給init
3、將初始化好的老師物件賦值給變數名res

'''

六:單例模式
實現方式1:classmethod

"""
import settings

class MySQL:
__instance = None

def __init__(self, ip, port):
self.ip = ip
self.port = port

@classmethod
def singleton(cls):
if cls.__instance:
return cls.__instance
cls.__instance = cls(settings.IP, settings.PORT)
return cls.__instance
obj1=MySQL("1.1.1.1",3306)
obj2=MySQL("1.1.1.2",3306)
print(obj1)
print(obj2)

obj3 = MySQL.singleton()
print(obj3)

obj4 = MySQL.singleton()
print(obj4)
"""

方式2:元類

"""
import settings

class Mymeta(type):
instance = None
def
init(self,class_name,class_bases,class_dic):
self.
instance=object.new(self) # Mysql類的物件
self.init(self.__instance,settings.IP,settings.PORT)

def __call__(self, *args, **kwargs):
if args or kwargs:
obj = object.__new__(self)
self.__init__(obj, *args, **kwargs)
return obj
else:
return self.__instance
MySQL=Mymeta(...)

class MySQL(metaclass=Mymeta):
def init(self, ip, port):
self.ip = ip
self.port = port

obj1 = MySQL("1.1.1.1", 3306)
obj2 = MySQL("1.1.1.2", 3306)
print(obj1)
print(obj2)

obj3 = MySQL()
obj4 = MySQL()

print(obj3 is obj4)
"""

方式3:裝飾器

"""
import settings

def outter(func): # func = MySQl類的記憶體地址
_instance = func(settings.IP,settings.PORT)
def wrapper(args,**kwargs):
if args or kwargs:
res=func(
args,**kwargs)
return res
else:
return _instance
return wrapper

@outter # MySQL=outter(MySQl類的記憶體地址) # MySQL=》wrapper
class MySQL:
def init(self, ip, port):
self.ip = ip
self.port = port

obj1 = MySQL("1.1.1.1", 3306)
obj2 = MySQL("1.1.1.2", 3306)
print(obj1)
print(obj2)

obj3 = MySQL()
obj4 = MySQL()
print(obj3 is obj4)
"""

瞭解:屬性查詢

class Mymeta(type):
n=444

# def __call__(self, *args, **kwargs): #self=<class '__main__.OldboyTeacher'>
# obj=self.__new__(self)
# print(self.__new__ is object.__new__) #True

class Bar(object):
# n=333

# def __new__(cls, *args, **kwargs):
# print('Bar.__new__')
pass

class Foo(Bar):
# n=222

# def __new__(cls, *args, **kwargs):
# print('Foo.__new__')
pass

class OldboyTeacher(Foo,metaclass=Mymeta):
# n=111

school='oldboy'

def __init__(self,name,age):
# self.n=0
self.name=name
self.age=age

def say(self):
print('%s says welcome to the oldboy to learn Python' %self.name)
# def __new__(cls, *args, **kwargs):
# print('OldboyTeacher.__new__')
obj=OldboyTeacher('egon',18)
print(obj.n)

print(OldboyTeacher.n)

call控制類的呼叫
class Foo:
def __call__(self, *args, **kwargs):
print('================>')
print(self)
print(args)
print(kwargs)


obj1 = Foo()
obj1(1,2,3,a=1,b=2) # 呼叫物件其實就是在呼叫物件類中定義的繫結方法__call__
#

# obj2 = int(10)

# obj2()

# obj3 = list([1, 2, 3])

# obj3()