পাইথনে সি লাইব্রেরি মোড়ানো: সি, সিথন বা সিটিপস?


284

আমি পাইথন অ্যাপ্লিকেশন থেকে একটি সি লাইব্রেরি কল করতে চাই। আমি পুরো এপিআই लपेटতে চাই না, কেবলমাত্র আমার ক্ষেত্রে প্রাসঙ্গিক ফাংশন এবং ডেটাটাইপ। আমি এটি দেখতে হিসাবে, আমার তিনটি পছন্দ আছে:

  1. সিতে একটি প্রকৃত এক্সটেনশন মডিউল তৈরি করুন সম্ভবত ওভারকিল, এবং আমি এক্সটেনশন রাইটিং শেখার ওভারহেড এড়াতে চাই।
  2. সি লাইব্রেরি থেকে পাইথনে প্রাসঙ্গিক অংশগুলি প্রকাশ করতে সাইথন ব্যবহার করুন ।
  3. ctypesবাহ্যিক গ্রন্থাগারের সাথে যোগাযোগ করার জন্য পাইথনে পুরো কাজটি করুন ।

আমি নিশ্চিত না যে 2) বা 3) আরও ভাল পছন্দ কিনা। 3 এর সুবিধাটি ctypesহ'ল এটি স্ট্যান্ডার্ড লাইব্রেরির অংশ, এবং ফলাফলযুক্ত কোডটি খাঁটি পাইথন হবে - যদিও আমি নিশ্চিত না যে সুবিধাটি আসলে কতটা বড়।

উভয় পছন্দ সঙ্গে আরও সুবিধা / অসুবিধা আছে? আপনি কোন পদ্ধতির পরামর্শ দিচ্ছেন?


সম্পাদনা করুন: আপনার সমস্ত জবাবের জন্য ধন্যবাদ, যে কেউ অনুরূপ কিছু করতে চাইছে তাদের জন্য তারা একটি ভাল সংস্থান সরবরাহ করে। অবশ্যই, সিদ্ধান্তটি এখনও একক মামলার জন্য নেওয়া দরকার — এমন কোনও উত্তর নেই "এই সঠিক জিনিস" সাজানোর উত্তর। আমার নিজের ক্ষেত্রে, আমি সম্ভবত টাইপগুলি নিয়ে যাব, তবে আমি অন্য কোনও প্রকল্পে সিথন চেষ্টা করার জন্যও অপেক্ষা করছি।

একক সত্য উত্তর না থাকায় একটি গ্রহণ করা কিছুটা স্বেচ্ছাচারী; আমি ফোগলবার্ডের উত্তরটি বেছে নিয়েছি কারণ এটি সিটিপস সম্পর্কে কিছু ভাল অন্তর্দৃষ্টি দেয় এবং এটি বর্তমানে সর্বাধিক-ভোট প্রাপ্ত উত্তরও। তবে, আমি একটি ভাল ওভারভিউ পেতে সমস্ত উত্তর পড়তে পরামর্শ দিই।

আবার ধন্যবাদ.


3
কিছু পরিমাণে, নির্দিষ্ট অ্যাপ্লিকেশন জড়িত (গ্রন্থাগারটি কী করে) পদ্ধতির পছন্দকে প্রভাবিত করতে পারে। আমরা হার্ডরিয়ের বিভিন্ন টুকরো (যেমন অ্যাসিলোস্কোপস) এর জন্য বিক্রেতার সরবরাহকৃত ডিএলএলগুলির সাথে কথা বলার জন্য সফলভাবে সাইটিপস ব্যবহার করেছি তবে আমি অংকিত প্রসেসিং লাইব্রেরির সাথে কথা বলার জন্য প্রথমে সিটিপগুলি বেছে নেব না, কারণ অতিরিক্ত ওভারহেড বনাম সাইথন বা এসডিজিআইজি।
পিটার হ্যানসেন

1
এখন আপনি যা খুঁজছিলেন তা আপনার কাছে রয়েছে। চারটি পৃথক উত্তর। (কেউ এসডিজিআইজিও পেয়েছে)। তার মানে এখন আপনি 3 এর পরিবর্তে 4 টি পছন্দ করেছেন
লুকা রাহনে

@ রালু এটিই আমিও করেছি :-) তবে গম্ভীরভাবে, আমি কোনও প্রো / কন টেবিল বা একটি একক উত্তর বলেছিলাম না যে "আপনার যা করা দরকার তা এখানে"। সিদ্ধান্ত গ্রহণের বিষয়ে যে কোনও প্রশ্নের উত্তম কারণ দেওয়া প্রতিটি সম্ভাব্য পছন্দের "অনুরাগীদের" দিয়ে দেওয়া উচিত। সম্প্রদায়কে ভোট দেওয়ার পরে তার নিজের অংশটি যেমন কাজ করে (তর্কগুলি দেখানো, সেগুলি আমার ক্ষেত্রে প্রয়োগ করা, সরবরাহিত উত্সগুলি পড়ুন ইত্যাদি) করে does দীর্ঘ গল্প সংক্ষিপ্ত: এখানে কিছু ভাল উত্তর আছে।
বালফা

সুতরাং আপনি কোন পদ্ধতির সাথে যেতে যাচ্ছেন? :)
ফোগলবার্ড

1
আমি যতদূর জানি (দয়া করে আমি ভুল হলে আমাকে সংশোধন করুন), সাইথন পাইরেক্সের একটি কাঁটাচামচ যার আরও বেশি বিকাশ এটিতে প্রবেশ করেছে, যা পাইরেক্সকে বেশ অচল করে দিয়েছে।
বালফা

উত্তর:


115

ctypes এটি দ্রুত সম্পন্ন করার জন্য আপনার সেরা বাজি, এবং আপনি এখনও পাইথন লিখছেন বলে কাজ করে আনন্দিত!

আমি সম্প্রতি একটি আবৃত FTDI ctypes ব্যবহার করে একটি ইউএসবি চিপ সঙ্গে যোগ স্থাপনের জন্য ড্রাইভার এবং এটি ছিল মহান। আমি এটি সব করে দিয়েছি এবং একেরও কম কাজের দিনে কাজ করেছি। (আমি কেবল আমাদের প্রয়োজনীয় ফাংশনগুলি প্রয়োগ করেছি, প্রায় 15 টি ফাংশন)।

আমরা আগে একই উদ্দেশ্যে একটি তৃতীয় পক্ষের মডিউল, পিইউএসবি ব্যবহার করছিলাম । পাইউসবি একটি আসল সি / পাইথন এক্সটেনশন মডিউল। কিন্তু পাইউএসবি জিআইএল মুক্তি দিচ্ছিল না যখন রিডিং / রাইটিং ব্লক করে যা আমাদের জন্য সমস্যা তৈরি করেছিল। তাই আমি সিটিপস ব্যবহার করে আমাদের নিজস্ব মডিউলটি লিখেছিলাম, যা দেশীয় ফাংশনগুলি কল করার সময় জিআইএল মুক্তি দেয়।

একটি বিষয় লক্ষণীয় যে সিটিপসগুলি #defineআপনি যে লাইব্রেরিতে ব্যবহার করছেন সেগুলির ধ্রুবক এবং স্টাফগুলি সম্পর্কে কেবলমাত্র ফাংশনগুলি জানতে পারবেন না, সুতরাং আপনার নিজের কোডে এই ধ্রুবকগুলিকে পুনরায় সংজ্ঞা দিতে হবে।

কোডটি কীভাবে দেখতে পেল তার উদাহরণ এখানে দেওয়া হয়েছে (প্রচুর পরিমাণে ছিটকে পড়েছে, কেবল আপনাকে এর সূচক দেখানোর চেষ্টা করছে):

from ctypes import *

d2xx = WinDLL('ftd2xx')

OK = 0
INVALID_HANDLE = 1
DEVICE_NOT_FOUND = 2
DEVICE_NOT_OPENED = 3

...

def openEx(serial):
    serial = create_string_buffer(serial)
    handle = c_int()
    if d2xx.FT_OpenEx(serial, OPEN_BY_SERIAL_NUMBER, byref(handle)) == OK:
        return Handle(handle.value)
    raise D2XXException

class Handle(object):
    def __init__(self, handle):
        self.handle = handle
    ...
    def read(self, bytes):
        buffer = create_string_buffer(bytes)
        count = c_int()
        if d2xx.FT_Read(self.handle, buffer, bytes, byref(count)) == OK:
            return buffer.raw[:count.value]
        raise D2XXException
    def write(self, data):
        buffer = create_string_buffer(data)
        count = c_int()
        bytes = len(data)
        if d2xx.FT_Write(self.handle, buffer, bytes, byref(count)) == OK:
            return count.value
        raise D2XXException

কেউ কেউ বিভিন্ন অপশন উপর কিছু বেঞ্চমার্ক করেছেন।

আমি প্রচুর ক্লাস / টেম্পলেট / ইত্যাদি সহ একটি সি ++ লাইব্রেরি গুটিয়ে রাখতে চাইলে আমি আরও দ্বিধাগ্রস্থ হতে পারি। কিন্তু ctypes structs মধ্যে ভাল কাজ করে এর এবং এমনকি করতে পারেন কলব্যাক পাইথন মধ্যে।


5
সিটিপিসের প্রশংসাগুলিতে যোগদান করা, তবে একটি (নথিভুক্ত) ইস্যুটি লক্ষ্য করুন: সিটিপস কাঁটাচামচ সমর্থন করে না। যদি আপনি সিটিপস ব্যবহার করে কোনও প্রক্রিয়া থেকে কাঁটাচামচ করেন, এবং পিতা বা মাতা এবং সন্তানের উভয় প্রক্রিয়া সিটিপস ব্যবহার অব্যাহত রাখে, আপনি ভাগ্যযুক্ত মেমোরি ব্যবহার করে সিটিপিসের সাথে করণীয় একটি বাজে বাগের উপর হোঁচট খেয়ে যাবেন।
ওরেেন শেমশ

1
@ ওরেনশেমেশ এই বিষয়টিতে আরও কিছু পড়ার আছে যা আপনি আমাকে নির্দেশ করতে পারেন? আমি মনে করি আমি বর্তমানে যে প্রকল্পে কাজ করছি তার সাথে আমি নিরাপদ থাকতে পারি, কারণ আমি বিশ্বাস করি যে কেবল পিতামাতার প্রক্রিয়াই ctypes(এর জন্য pyinotify) ব্যবহার করে তবে আমি আরও সমস্যাটি আরও ভালভাবে বুঝতে চাই।
zigg

এই উত্তরণটি আমাকে অনেক সাহায্য করে One thing to note is that ctypes won't know about #define constants and stuff in the library you're using, only the functions, so you'll have to redefine those constants in your own code.তাই, আমাকে সেখানে থাকা winioctl.h
কনস্ট্যান্টগুলি

পারফরম্যান্স সম্পর্কে কীভাবে? ctypesসি-এক্সটেনশনের তুলনায় অনেক ধীর গতির কারণ বাধাটি পাইথন থেকে সি পর্যন্ত ইন্টারফেস
টমসওয়ায়ার

154

সতর্কতা: সামনে সাইথন কোর বিকাশকারীর মতামত।

আমি প্রায় সবসময় সিথাইনের উপরে সাইথনের প্রস্তাব দিই। কারণটি হ'ল এটির অনেক মসৃণ আপগ্রেডের পথ রয়েছে। আপনি যদি সিটিপস ব্যবহার করেন তবে অনেকগুলি প্রথমে সহজ হবে এবং সংকলন ছাড়াই প্লে পাইথনে আপনার এফএফআই কোডটি লিখতে অবশ্যই শীতল that যাইহোক, এক পর্যায়ে, আপনি প্রায় অবশ্যই খুঁজে পাবেন যে আপনি আপনার সি লাইব্রেরিতে অনেকগুলি কল করতে হবে, হয় একটি লুপে বা আন্তঃনির্ভরশীল কলগুলির একটি দীর্ঘ সিরিজের, এবং আপনি এটির গতি বাড়িয়ে দিতে চান। এটি সেই বিন্দু যেখানে আপনি লক্ষ্য করবেন যে আপনি সিটিপিস দিয়ে এটি করতে পারবেন না। অথবা, যখন আপনার কলব্যাক ফাংশনগুলির প্রয়োজন হয় এবং আপনি যখন দেখতে পান যে আপনার পাইথন কলব্যাক কোডটি একটি বাধা হয়ে দাঁড়িয়েছে, আপনি এটির গতি বাড়িয়ে তুলতে এবং / অথবা এটিকে সি তেও সরিয়ে নিতে চাই। আবার, আপনি সিটিপিস দিয়ে এটি করতে পারবেন না।

সিথন, ওটিওএইচ দিয়ে আপনি মোড়ানো এবং কলিং কোডটি আপনার ইচ্ছে মতো পাতলা বা ঘন করতে সম্পূর্ণ মুক্ত free আপনি নিয়মিত পাইথন কোড থেকে আপনার সি কোডে সাধারণ কলগুলি দিয়ে শুরু করতে পারেন এবং সিথন এগুলিকে কোনও অতিরিক্ত কলিং ওভারহেড ছাড়াই স্থানীয় সি কলগুলিতে অনুবাদ করবেন এবং পাইথন প্যারামিটারের জন্য অত্যন্ত কম রূপান্তর ওভারহেড সহ with যখন আপনি লক্ষ্য করেন যে আপনি যখন আপনার সি লাইব্রেরিতে অনেক বেশি ব্যয়বহুল কল করছেন তখন আপনাকে আরও বেশি পারফরম্যান্সের প্রয়োজন রয়েছে, আপনি আপনার পার্শ্ববর্তী পাইথন কোডটি স্থির প্রকারের সাথে টিকিয়ে রাখতে শুরু করতে পারেন এবং সিথন আপনার জন্য সরাসরি সিটিতে এটি অপ্টিমাইজ করতে দিন। অথবা, কল এড়াতে এবং অ্যালগোরিদমিকভাবে আপনার লুপগুলিকে বিশেষ করতে এবং শক্ত করতে আপনি সিথনে আপনার সি কোডের কিছু অংশ পুনরায় লেখা শুরু করতে পারেন। এবং আপনার যদি দ্রুত কলব্যাকের প্রয়োজন হয়, কেবল উপযুক্ত স্বাক্ষর সহ একটি ফাংশন লিখুন এবং সরাসরি সি কলব্যাক রেজিস্ট্রিতে এটি পাস করুন। আবার কোনও ওভারহেড নেই এবং এটি আপনাকে সাধারণ সি কলিং পারফরম্যান্স দেয়। এবং খুব কম সম্ভাব্য ক্ষেত্রে আপনি সাইথনে আপনার কোডটি দ্রুত পর্যাপ্তরূপে পেতে না পারলে আপনি এখনও এর সত্যিকারের সমালোচনামূলক অংশগুলি সি (বা সি ++ বা ফোর্টরান) এ পুনরায় লেখার বিষয়ে বিবেচনা করতে পারেন এবং এটি আপনার সিথন কোড থেকে প্রাকৃতিকভাবে এবং স্থানীয়ভাবে কল করতে পারেন। তবে তারপরে, এটি কেবলমাত্র একমাত্র বিকল্পের পরিবর্তে শেষ অবলম্বন হয়ে ওঠে।

সুতরাং, সিটিপসগুলি সাধারণ জিনিসগুলি করা এবং দ্রুত কিছু চালানো পেতে দুর্দান্ত। যাইহোক, জিনিসগুলি বাড়তে শুরু করার সাথে সাথে আপনি সম্ভবত এমন পর্যায়ে পৌঁছে যাবেন যেখানে আপনি লক্ষ্য করেছেন যে আপনি শুরু থেকেই সিথনকে আরও ভাল ব্যবহার করেছেন।


4
এটি +1 ভাল পয়েন্ট, অনেক অনেক ধন্যবাদ! যদিও আমি ভাবছি যদি কেবল বাধা অংশগুলি সিথনে স্থানান্তর করা সত্যিই ওভারহেডের অনেক বেশি হয়। তবে আমি একমত, আপনি যদি কোনও ধরণের পারফরম্যান্স সমস্যা আশা করেন তবে আপনি শুরু থেকেই সাইথনকে কাজে লাগাতে পারেন।
বালফা

এটি এখনও সি এবং পাইথন উভয়ের সাথেই অভিজ্ঞ প্রোগ্রামারদের ধরে রাখে? সেক্ষেত্রে কেউ যুক্তি দিতে পারে যে পাইথন / সিটিপস আরও ভাল পছন্দ, যেহেতু সি লুপস (সিমডি) এর ভেক্টরাইজেশন কখনও কখনও আরও সোজা হয়। তবে, এগুলি বাদে আমি কোনও সিথনের ত্রুটিগুলি ভাবতে পারি না।
অ্যালেক্স ভ্যান হুটেন

উত্তর করার জন্য ধন্যবাদ! সাইথনের বিষয়ে আমার যে সমস্যাটি হয়েছিল তা হ'ল বিল্ড প্রক্রিয়াটি ঠিকঠাক হচ্ছে (তবে এর আগে আমার সাথে পাইথন মডিউলটি কখনই লেখার দরকার নেই) - আমার কি এটি আগে সংকলন করা উচিত, অথবা সিডিস্ট এবং অনুরূপ প্রশ্নগুলিতে সিথন উত্স ফাইলগুলি অন্তর্ভুক্ত করা উচিত। কারও ক্ষেত্রে একই সমস্যা / সন্দেহ থাকলে আমি এ সম্পর্কে একটি ব্লগ পোস্ট লিখেছিলাম:
মার্টিনসোসিক

উত্তর করার জন্য ধন্যবাদ! আমি যখন সিথন ব্যবহার করি তখন একটি অপূর্ণতা হ'ল অপারেটর ওভারলোডিং পুরোপুরি কার্যকর হয় না (যেমন __radd__)। আপনি নিজের শ্রেণীর বিল্টিন ধরণের (যেমন intএবং float) সাথে ইন্টারঅ্যাক্ট করার পরিকল্পনা করার সময় এটি বিশেষভাবে বিরক্তিকর । এছাড়াও, সিথনের যাদু পদ্ধতিগুলি সাধারণভাবে কিছুটা বগি।
মনোলিথ

100

সিথন নিজেই একটি দুর্দান্ত সরঞ্জাম, শেখার পক্ষে মূল্যবান এবং আশ্চর্যজনকভাবে পাইথন সিনট্যাক্সের কাছাকাছি। আপনি যদি নম্পির সাথে কোনও বৈজ্ঞানিক কম্পিউটিং করেন, তবে সাইথন হ'ল উপায়, কারণ এটি দ্রুত ম্যাট্রিক্স অপারেশনের জন্য নম্পির সাথে একীভূত হয়।

সিথন পাইথন ভাষার সুপারস্টেট। আপনি এটিতে যে কোনও বৈধ পাইথন ফাইল নিক্ষেপ করতে পারেন এবং এটি একটি বৈধ সি প্রোগ্রাম আউট করবে। এই ক্ষেত্রে, সিথন কেবলমাত্র অন্তর্নিহিত সিপিথন এপিআই-তে পাইথন কলগুলি ম্যাপ করবে। এটি সম্ভবত একটি 50% গতিবেগের ফলাফল দেয় কারণ আপনার কোডটির আর ব্যাখ্যা করা হয়নি।

কিছু অপ্টিমাইজেশান পেতে, আপনাকে সিথনকে আপনার কোড সম্পর্কে অতিরিক্ত তথ্য বলা শুরু করতে হবে, যেমন টাইপ ডিক্লেয়ারেশন। যদি আপনি এটি পর্যাপ্ত পরিমাণে বলেন, এটি কোডটি নিখুঁত সি পর্যন্ত সিদ্ধ করতে পারে, অর্থাত, পাইথনের লুপের জন্য ল একটি সিতে লুপ হয়ে যায় Here আপনি এখানে প্রচুর গতিবেগ দেখবেন। আপনি এখানে বাহ্যিক সি প্রোগ্রামগুলির সাথেও লিঙ্ক করতে পারেন।

সিথন কোড ব্যবহার করাও অবিশ্বাস্যরকম সহজ। আমি ভেবেছিলাম ম্যানুয়ালটি এটিকে কঠিন করে তোলে। আপনি আক্ষরিকভাবে শুধু:

$ cython mymodule.pyx
$ gcc [some arguments here] mymodule.c -o mymodule.so

এবং তারপরে আপনি import mymoduleআপনার পাইথন কোডটি করতে পারেন এবং এটি সম্পূর্ণরূপে ভুলে যান যে এটি সিতে সংকলিত হয়েছে entire

যাইহোক, সিথন সেটআপ করা এবং ব্যবহার শুরু করা এত সহজ, তাই আমি এটি আপনার প্রয়োজন অনুসারে এটি চেষ্টা করার চেষ্টা করার পরামর্শ দিই। এটি যে অপব্যয় হবে তা যদি আপনি সন্ধান করেন এমন সরঞ্জামটি না হয়ে পরিণত হয়।


1
সমস্যা নেই. সিথন সম্পর্কে দুর্দান্ত জিনিস হ'ল আপনি যা চান তা কেবল শিখতে পারেন। আপনি যদি কেবলমাত্র একটি সামান্য উন্নতি চান, আপনাকে যা করতে হবে তা হ'ল আপনার পাইথন ফাইলগুলি সংকলন করতে হবে এবং আপনার কাজ শেষ।
কার্ল

18
"আপনি এটিতে যে কোনও বৈধ পাইথন ফাইল নিক্ষেপ করতে পারেন এবং এটি একটি বৈধ সি প্রোগ্রাম আউট করবে।" <- বেশ কিছু নয়, কিছু সীমাবদ্ধতা রয়েছে: ডকস.সাইথন.আর.সিআরসি / ইউজারগাইড / লিমিটেশনস html সম্ভবত বেশিরভাগ ব্যবহারের ক্ষেত্রে সমস্যা নয়, তবে কেবল সম্পূর্ণ হতে চেয়েছিলেন।
র্যান্ডি সিরিয়িং

7
প্রতিটি প্রকাশের সাথে ইস্যুগুলি কম পাওয়া যাচ্ছে, সেই পৃষ্ঠাটিতে এখন বলা হয়েছে যে "বেশিরভাগ সমস্যা 0.15 তে সমাধান করা হয়েছে"।
হেনরি গোমারসাল 23'12

3
যোগ করার জন্য, সিথন কোড আমদানির জন্য একটি সহজ উপায় আছে: আপনার সিথন কোডটি mymod.pyxমডিউল হিসাবে লিখুন এবং তারপর করুন import pyximport; pyximport.install(); import mymodএবং সংকলনটি পর্দার আড়ালে ঘটে।
কৌশিক ঘোষ

3
@ কৌশিক এমনকি সহজ পিপিআইপিথন.আর.পিআইপি / রুনসিথন । শুধু ব্যবহার runcython mymodule.pyx। এবং পাইক্সিম্পোর্টের বিপরীতে আপনি এটিকে আরও চাহিদাযুক্ত লিঙ্কিংয়ের কাজে ব্যবহার করতে পারেন। কেবলমাত্র সতর্কতা হ'ল আমিই সেই ব্যক্তি যিনি এটির জন্য 20 লাইনের বাশ লিখেছিলেন এবং এটি পক্ষপাতদুষ্ট হতে পারে।
রাসেল স্টাওয়ার্ট

42

একটি পাইথন অ্যাপ্লিকেশন থেকে C লাইব্রেরি কলিং জন্য রয়েছে cffi , যার জন্য নতুন বিকল্প নেই ctypes । এটি এফএফআইয়ের জন্য একটি নতুন চেহারা এনেছে:

  • এটি একটি মনোমুগ্ধকর, পরিষ্কার উপায়ে ( সিটিপের বিপরীতে ) সমস্যাটি পরিচালনা করে
  • পাইথন নন কোড লেখার দরকার নেই (যেমন এসডাব্লাগআইজি, সিথন , ...)

স্পষ্টভাবে পথ যাওয়ার জন্য মোড়ানো , যেমন ওপি চেয়েছিলেন। সেগুলি হট লুপগুলি নিজে লেখার জন্য সাইথন দুর্দান্ত শোনায় তবে ইন্টারফেসের জন্য সিএফআই কেবল সিটিপাইস থেকে সরাসরি আপগ্রেড।
উড়ন্ত ভেড়া

21

আমি অন্য একজনকে সেখানে ফেলে দেব: এসডিজিআইজি

এটি শিখতে সহজ, অনেকগুলি সঠিক কাজ করে এবং আরও অনেকগুলি ভাষা সমর্থন করে যাতে শেখার সময়টি এটি বেশ কার্যকর হতে পারে।

আপনি যদি SWIG ব্যবহার করেন, আপনি একটি নতুন অজগর এক্সটেনশন মডিউল তৈরি করছেন, তবে এসডিজিআইজি আপনার জন্য বেশিরভাগ ভারী উত্তোলন করছে।


18

ব্যক্তিগতভাবে, আমি সি তে একটি এক্সটেনশন মডিউল লিখব পাইথন সি এক্সটেনশানগুলি দ্বারা ভয় দেখাবেন না - তারা লিখতে মোটেই কঠিন নয়। ডকুমেন্টেশন খুব স্পষ্ট এবং সহায়ক। পাইথনে যখন আমি প্রথম সি এক্সটেনশন লিখেছিলাম তখন আমার মনে হয় কীভাবে লিখতে হয় তা নির্ধারণ করতে আমার প্রায় এক ঘন্টা সময় লেগেছিল - মোটেও বেশি সময় নয়।


একটি সি লাইব্রেরি মোড়ানো। আপনি এখানে কোডটি আসলে খুঁজে পেতে পারেন: github.com/mdippery/lehmer
mipadi

1
@ ফোরিভাল: কোডটি আসলে এতটা কার্যকর ছিল না এবং এখান থেকে আরও ভাল এলোমেলো সংখ্যা জেনারেটর রয়েছে। আমার কম্পিউটারে আমার কেবল একটি ব্যাকআপ রয়েছে।
মিপাদি

2
একমত। পাইথনের সি-এপিআই দেখতে যতটা ভয়ঙ্কর দেখা যায় না (ধরে নিলে আপনি সি জানেন)। তবে সিটিতে এক্সটেনশন লেখার সময় অজগর এবং এটি গ্রন্থাগার, সংস্থান এবং বিকাশকারীদের জলাধারের সাথে আলাদা নয় you're সম্ভবত এটির একমাত্র ত্রুটি (সাধারণত সিটিতে লেখার সাথে আসে সেগুলি ব্যতীত)।
নুব সাইবোট

1
@mipadi: ভাল, কিন্তু তারা পাইথন 2.x এবং 3.x মধ্যবর্তী পার্থক্য তাই এটি আরো Cython ব্যবহার করার জন্য আপনার এক্সটেনশন লিখতে সুবিধাজনক, Cython চিত্রে আউট সব বিস্তারিত আছে এবং তারপর পাইথন 2.x জন্য উত্পন্ন সি কোড কম্পাইল বা 3.x প্রয়োজনীয় হিসাবে।
0xC0000022L

2
@ মিপাডি মনে হচ্ছে গিথুব লিঙ্কটি মারা গেছে এবং এটি সংরক্ষণাগার.অর্গে উপলব্ধ বলে মনে হচ্ছে না, আপনার কি ব্যাকআপ আছে?
jrh

11

সিটিপস দুর্দান্ত যখন আপনি ইতিমধ্যে ডিল করার জন্য একটি সংকলিত লাইব্রেরি ব্লব পেয়েছেন (যেমন ওএস লাইব্রেরি হিসাবে)। কলিং ওভারহেড গুরুতর, তবে, আপনি যদি লাইব্রেরিতে প্রচুর কল করতে থাকেন এবং আপনি যেভাবেই সি কোড লিখতে যাচ্ছেন (বা কমপক্ষে এটি সংকলন করছেন), আমি যেতে বলব cython । এটি খুব বেশি কাজ নয় এবং ফলস্বরূপ পাইড ফাইলটি ব্যবহার করা আরও দ্রুত এবং আরও বেশি পাইথোনিক হবে।

আমি ব্যক্তিগতভাবে পাইথন কোডের দ্রুত গতির জন্য সিথন ব্যবহার করার প্রবণতা পাই (লুপস এবং পূর্ণসংখ্যার তুলনা দুটি ক্ষেত্র যেখানে সিথন বিশেষত জ্বলজ্বল করে) এবং যখন আরও কিছু যুক্ত কোড / জড়িত অন্যান্য লাইব্রেরিগুলির জড়িত থাকে তখন আমি বুস্ট.পাইথনে ফিরে যাব । বুস্ট.পিথন সেট আপ করা চতুর হতে পারে তবে আপনি এটি কাজ করে নিলে এটি সি / সি ++ কোডটি সোজা করে মোড়ানো করে তোলে।

ন্যুটি মোড়ানোর ক্ষেত্রে সাইথনও দুর্দান্ত (যা আমি সায়পাই ২০০৯ এর কার্যক্রিয়া থেকে শিখেছি ), তবে আমি আড়ষ্ট ব্যবহার করি নি, তাই আমি এ বিষয়ে কোনও মন্তব্য করতে পারি না।


11

আপনার যদি ইতিমধ্যে সংজ্ঞায়িত এপিআই সহ একটি লাইব্রেরি থাকে তবে আমি মনে করি ctypesসেরা বিকল্প, কারণ আপনাকে কেবলমাত্র কিছুটা প্রাথমিককরণ করতে হবে এবং তারপরে কমবেশি আপনি লাইব্রেরিকে কল করুন the

আমি মনে করি সিথন বা সি-তে একটি এক্সটেনশন মডিউল তৈরি করা (যা খুব বেশি কঠিন নয়) আপনার যখন নতুন কোড দরকার হয়, উদাহরণস্বরূপ library লাইব্রেরিটি কল করা এবং কিছু জটিল, সময়সাপেক্ষ কাজ করা এবং তারপরে ফলাফলটি পাইথনে পৌঁছে দেওয়া আরও কার্যকর।

সাধারণ প্রোগ্রামগুলির জন্য আরেকটি পদ্ধতি হ'ল সরাসরি আলাদা প্রক্রিয়া করা হয় (বাহ্যিকভাবে সংকলিত), ফলাফলকে স্ট্যান্ডার্ড আউটপুট এ আউটপুট করে সাব-প্রসেস মডিউল দিয়ে কল করে। কখনও কখনও এটি সবচেয়ে সহজ পদ্ধতির।

উদাহরণস্বরূপ, আপনি যদি কনসোল সি প্রোগ্রাম তৈরি করেন যা সেভাবে কমবেশি কাজ করে

$miCcode 10
Result: 12345678

আপনি পাইথন থেকে কল করতে পারেন

>>> import subprocess
>>> p = subprocess.Popen(['miCcode', '10'], shell=True, stdout=subprocess.PIPE)
>>> std_out, std_err = p.communicate()
>>> print std_out
Result: 12345678

কিছুটা স্ট্রিং ফরমেটিং করে আপনি যেভাবে চান ফলাফলটি নিতে পারেন। আপনি স্ট্যান্ডার্ড ত্রুটি আউটপুটও ক্যাপচার করতে পারেন, সুতরাং এটি বেশ নমনীয়।


যদিও এই উত্তরের সাথে কোনও ভুল নেই, লোকেরা সাবধান হওয়া উচিত যদি অন্যদের দ্বারা অ্যাক্সেসের জন্য কোডটি চালু করা হয় তবে সাব-প্রসেসিং কল করার সাথে কোডটি shell=Trueসহজেই একরকম শোষণের ফলস্বরূপ হতে পারে যখন কোনও ব্যবহারকারী সত্যই শেল পায়। এটি ঠিক আছে যখন বিকাশকারী একমাত্র ব্যবহারকারীর হয় তবে বিশ্বে খুব বিরক্তিকর pricks একটি গোছা আছে ঠিক কিছু এর জন্য অপেক্ষা করছে।
বেন

7

এখানে একটি ইস্যু রয়েছে যা আমাকে সিটিপগুলি ব্যবহার করেছে এবং সিথন নয় এবং অন্যান্য উত্তরে এর উল্লেখ নেই।

সিটি টাইপ ব্যবহার করা ফলাফলটি আপনি মোটেও ব্যবহার করছেন সংকলকের উপর নির্ভর করে না। আপনি দেশী ভাগ করা লাইব্রেরিতে সংকলিত হতে পারে এমন কম-বেশি ভাষা ব্যবহার করে একটি লাইব্রেরি লিখতে পারেন। এটি কোনও বিষয় নয়, কোন সিস্টেম, কোন ভাষা এবং কোনটি সংকলক। সিথন অবশ্য অবকাঠামো দ্বারা সীমাবদ্ধ। উদাহরণস্বরূপ, আপনি যদি উইন্ডোতে ইন্টেল সংকলক ব্যবহার করতে চান তবে সিথনের কাজ করা আরও বেশি জটিল: আপনার সাইথনের সংকলকটি "ব্যাখ্যা" করা উচিত, এই সঠিক সংকলক সহ কিছু পুনরায় সংকলন করা উচিত, যা উল্লেখযোগ্যভাবে বহনযোগ্যতার সীমাবদ্ধ করে।


4

আপনি যদি উইন্ডোজকে টার্গেট করে চলেছেন এবং কিছু মালিকানাধীন সি ++ লাইব্রেরি গুটিয়ে রাখতে চান, তবে শীঘ্রই আপনি আবিষ্কার করতে পারেন যে msvcrt***.dll(ভিজ্যুয়াল সি ++ রানটাইম) এর বিভিন্ন সংস্করণ সামান্য বেমানান।

এর অর্থ এই যে আপনি ব্যবহার করতে সক্ষম নাও হতে পারে Cythonযেহেতু ফলে wrapper.pydবিরুদ্ধে লিঙ্ক করা হয়েছে msvcr90.dll (পাইথন 2.7) বা msvcr100.dll (পাইথন 3.x) । আপনি যে লাইব্রেরিটি মুড়ে রাখছেন তা যদি রানটাইমের বিভিন্ন সংস্করণের সাথে সংযুক্ত থাকে, তবে আপনার ভাগ্য খুব খারাপ।

তারপরে জিনিসগুলি কাজ করার জন্য আপনাকে সি ++ লাইব্রেরির জন্য সি র‌্যাপার তৈরি করতে হবে, সেই মোড়কটিকে msvcrt***.dllআপনার সি ++ লাইব্রেরির একই সংস্করণের বিপরীতে লিঙ্ক করুন । এবং তারপরে ctypesরানটাইমে আপনার হ্যান্ড-রোলড র‍্যাপার ডেলিকে গতিশীলভাবে লোড করতে ব্যবহার করুন ।

সুতরাং এখানে অনেক ছোট ছোট বিবরণ রয়েছে, যা নীচের নিবন্ধে দুর্দান্তভাবে বর্ণনা করা হয়েছে:

"সুন্দর নেটিভ লাইব্রেরি (পাইথনে) ": http://lucumr.pocoo.org/2013/8/18/be সুন্দর-native-libraries/


মাইক্রোসফ্ট সংকলকগুলির সামঞ্জস্যতার সাথে আপনি যে সমস্যাগুলি নিয়ে এসেছেন তার সাথে এই নিবন্ধটির কোনও সম্পর্ক নেই। উইন্ডোজে কাজ করা সাইথনের এক্সটেনশনগুলি পাওয়া খুব কঠিন নয়। আমি বেশ কিছু কিছুর জন্য MinGW ব্যবহার করতে সক্ষম হয়েছি। একটি ভাল পাইথন বিতরণ যদিও সাহায্য করে।
আইয়ানএইচ

2
উইন্ডোজগুলিতে কোনও সম্ভাব্য সমস্যা উল্লেখ করার জন্য +1 (এটি বর্তমানে আমিও করছি ...)। @ আইএনএইচএইচ এটি সাধারণভাবে উইন্ডোজ সম্পর্কে কম, তবে আপনি যদি অজগর বিতরণটির সাথে মেলে না এমন কোনও তৃতীয় পক্ষের লাইবের সাথে আটকে থাকেন তবে এটি গোলযোগ।
সেবাস্তিয়ান


2

আমি জানি এটি একটি পুরানো প্রশ্ন তবে আপনি যখন জিনিসগুলি সন্ধান করেন তখন এই বিষয়টি গুগলে আসে এবং ctypes vs cythonএখানে বেশিরভাগ উত্তরগুলি ইতিমধ্যে দক্ষ যারা তাদের লিখেছেন cythonবা cযা সেগুলি শেখার জন্য আপনার যে বিনিয়োগের প্রয়োজন হয়েছিল তা প্রতিফলিত করে না আপনার সমাধান বাস্তবায়ন। আমি দুজনেই একজন সম্পূর্ণ শিক্ষানবিস। আমি এর cythonআগে কখনও স্পর্শ করিনি, এবং এর খুব কম অভিজ্ঞতাও করেছি c/c++

গত দুদিন ধরে, আমি আমার কোডের একটি পারফরম্যান্স ভারী অংশটি পাইথনের চেয়ে আরও নিম্ন স্তরের কিছুতে অর্পণের একটি উপায় খুঁজছিলাম। আমি উভয় মধ্যে আমার কোড বাস্তবায়িত ctypesএবং Cython, যা দুটি সরল ফাংশন মূলত গঠিত।

আমার কাছে একটি বিশাল স্ট্রিং তালিকা ছিল যা প্রক্রিয়াজাতকরণের প্রয়োজন। নোটিশ listএবং string। উভয় প্রকারের টাইপের সাথে পুরোপুরি cমিল নেই, কারণ পাইথন স্ট্রিংগুলি ডিফল্ট ইউনিকোড এবং cস্ট্রিংগুলি হয় না। অজগর তালিকাগুলি কেবল গ এর অ্যারে নয়।

এই আমার রায়। ব্যবহার cython। এটি অজগরকে আরও সাবলীলভাবে সংহত করে এবং সাধারণভাবে কাজ করা সহজ। যখন কোনও ভুল হয়ে যায় ctypesকেবল আপনাকে সেগফল্ট ছুড়ে দেয়, cythonযখনই এটি সম্ভব হয় কমপক্ষে আপনাকে স্ট্যাক ট্রেস দিয়ে সতর্কতা সংকলন দেয় এবং আপনি খুব সহজেই একটি বৈধ পাইথন বস্তুটি সহজেই ফিরিয়ে দিতে পারেন cython

একই ক্রিয়াকলাপটি বাস্তবায়নের জন্য দু'জনের জন্য আমার কতটা সময় বিনিয়োগ করতে হবে তার একটি বিশদ বিবরণ এখানে। আমি খুব কম সি / সি ++ প্রোগ্রামিং করেছিলাম:

  • Ctypes:

    • আমার ইউনিকোড স্ট্রিংয়ের তালিকাটি কীভাবে এসি সামঞ্জস্যপূর্ণ ধরণের রূপান্তর করতে হয় তা নিয়ে গবেষণা সম্পর্কে প্রায় 2 ঘন্টা।
    • এসি ফাংশন থেকে কীভাবে স্ট্রিংটি সঠিকভাবে ফিরিয়ে আনতে হবে তার প্রায় এক ঘন্টা। এখানে আমি আসলে আমার নিজের সমাধান প্রদান করা তাই একবার আমি ফাংশন লিখেছেন।
    • কোডটি সিতে লিখতে প্রায় আধ ঘন্টা, এটি একটি গতিশীল লাইব্রেরিতে সংকলন করুন।
    • 10 মিনিট পাইথনে পরীক্ষার কোড লিখতে cকোডটি কাজ করে কিনা তা খতিয়ে দেখার জন্য ।
    • কিছু পরীক্ষা করে cকোডটি পুনরায় সাজানোর প্রায় এক ঘন্টা ।
    • তারপরে আমি কোডটিকে cআসল কোড বেসে প্লাগ করেছিলাম এবং দেখেছি যে মডিউলটির ctypesসাথে এটি ভাল খেলছে না multiprocessingকারণ হ্যান্ডলারটি ডিফল্টরূপে বাছাইযোগ্য নয়।
    • প্রায় 20 মিনিটের মধ্যে আমি আমার কোডটি multiprocessingমডিউলটি ব্যবহার না করার জন্য পুনরায় সাজিয়েছি এবং আবার চেষ্টা করেছি।
    • তারপরে আমার cকোডে দ্বিতীয় ফাংশনটি আমার কোড বেসে সেগফাল্ট উত্পন্ন করেছে যদিও এটি আমার পরীক্ষার কোডটি পাস করেছে। ওয়েল, প্রান্তের কেসগুলি ভালভাবে পরীক্ষা না করার জন্য এটি সম্ভবত আমার দোষ, আমি একটি দ্রুত সমাধানের সন্ধান করছিলাম।
    • প্রায় 40 মিনিটের জন্য আমি এই সিগফল্টগুলির সম্ভাব্য কারণগুলি নির্ধারণ করার চেষ্টা করেছি।
    • আমি আমার ফাংশন দুটি লাইব্রেরিতে বিভক্ত করেছি এবং আবার চেষ্টা করেছি tried এখনও আমার দ্বিতীয় ফাংশনের জন্য সেগফোল্টস ছিল।
    • আমি দ্বিতীয় ফাংশনটি ছেড়ে যেতে এবং cকোডের প্রথম ফাংশনটি ব্যবহার করার সিদ্ধান্ত নিয়েছিলাম এবং পাইথন লুপটি এটি ব্যবহার করে যা দ্বিতীয়টি বা তৃতীয় পুনরাবৃত্তির সময় আমি UnicodeErrorকিছু পজিশনে একটি বাইট ডিকোডিং না করি যদিও আমি এনকোড করেছি এবং কখনও ডিকোড করেছি স্পষ্টভাবে।

এই মুহুর্তে, আমি একটি বিকল্প অনুসন্ধান করার সিদ্ধান্ত নিয়েছি এবং এটি অনুসন্ধান করার সিদ্ধান্ত নিয়েছি cython:

  • Cython
    • সাইথন হ্যালো ওয়ার্ল্ড পড়ার 10 মিনিট ।
    • পরিবর্তে কীভাবে সিথন ব্যবহার করবেন সে সম্পর্কে 15 মিনিট এসও পরীক্ষা করে দেখুন ।setuptoolsdistutils
    • সিথনের ধরণ এবং অজগর প্রকারভেদে 10 মিনিট পঠন । আমি শিখেছি স্থির টাইপিংয়ের জন্য আমি বিল্টিন পাইথনের বেশিরভাগ ধরণের ব্যবহার করতে পারি।
    • সিথনের ধরণের সাথে আমার অজগর কোডটি পুনরায় নোট করার 15 মিনিট।
    • setup.pyআমার কোডবেসে সংকলিত মডিউলটি ব্যবহার করতে আমার পরিবর্তন করার 10 মিনিট ।
    • মডিউলটিতে সরাসরি multiprocessingকোডবেসের সংস্করণে প্লাগ ইন করা হয়েছে । এটা কাজ করে।

রেকর্ডের জন্য, আমি অবশ্যই আমার বিনিয়োগের সঠিক সময়গুলি পরিমাপ করি নি। এটি খুব ভাল ক্ষেত্রে হতে পারে যে আমি সিটিপস নিয়ে কাজ করার সময় প্রয়োজনীয় মানসিক প্রচেষ্টার কারণে আমার সময় সম্পর্কে আমার ধারণাটি একটু মনোযোগী হয়েছিল। তবে এটির সাথে cythonএবং আচরণের অনুভূতিটি প্রকাশ করা উচিতctypes

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.